douxiong1994 2015-12-28 19:00
浏览 48
已采纳

GO应用程序和mongodb的干净通用项目结构

I want to build an API based application using GO and MongoDB. I'm from Asp.net MVC background. Probably if I make an architecture with MVC web application things to be consider are

  1. Separation of concerns(SoC)

    • DataModel
    • BusinessEntities
    • BusinessServices
    • Controllers
  2. Dependeny Injection and Unity of Work

  3. Unit Testing
    • MoQ or nUnit
  4. Integration with UI frameworks
    • Angularjs or others
  5. RESTful urls that enables SEO

Below architecture could be a solution for my need in MVC based appications

enter image description here

There are resources around the web to build Asp.Net or Java based applications, but I have not find solution to Golang application architecture.

Yes GO is different to C# or Java, but still there are Structs, Interfaces to create reusable code and a generic application architecture. Consider above points in mind, how we can make a clean and reusable project structure in GO applications and a generic repositories for DB(Mongodb) transactions. Any web resources also a great point to start.

  • 写回答

5条回答 默认 最新

  • douman9420 2016-01-07 19:35
    关注

    It depends on your own style and rules, in my company, we develop our projects this way:

    • Configuration is determined by environment variables, so we have a company/envs/project.sh file which has to be evaluated before service (outside the project in the image).
    • We add a zscripts folder that contains all extra scripts, like adding users or publishing a post. Intended to be used only for debug proposes.
    • Data models (entities) are in a package called project/models.
    • All controllers and views (HTML templates) are categorized into "apps" or "modules". We use the REST path as main group delimiter, so path /dogs goes to package project/apps/dogs and /cats to project/apps/cats.
    • Managers are in their separated package at project's root project/manager.
    • Static files (.css, .png, .js, etc.) are located at project/static/[app/]. Sometimes is required to have the optional [app/] folder, but it only happens when two apps have dashboards or conflicting file names. Most of cases you won't need to use [app/] for static resources.

    Managers

    We call a manager, a package that contains pure functions which helps apps to perform its task, for example, databases, cache, S3 storage, etc. We initialize each manager calling package.Startup() before we start to listen, and finalize calling package.Finalize() when program is interrupted.

    An example of a manager could be project/cache/cache.go:

    type Config struct {
        RedisURL string `envconfig:"redis_url"`
    }
    
    var config Config
    var client *redis.Client
    
    func Startup(c Config) error {
       config = c
       client, err := redis.Dial(c.RedisURL)
       return err
    }
    
    func Set(k,v string) error {
       return client.Set(k, v)
    }
    

    in main.go (or your_thing_test.go):

    var spec cache.Config
    envconfig.Process("project", &spec)
    
    cache.Startup(spec)
    

    And in a app (or module):

    func SetCacheHandler(_ http.ResponseWriter, _ *http.Request){
       cache.Set("this", "rocks")
    }
    

    Modules

    A module is a container of views and controllers that are isolated from other modules, using our configuration I would recommend to not create dependencies between modules. Modules are also called apps.

    Each module configures its routes using a router, sub-router or what your framework provides, for example (file project/apps/dogs/configure.go):

    func Configure(e *echo.Echo) {
        e.Get("/dogs", List)
    }
    

    Then, all handlers live in project/apps/dogs/handlers.go:

    // List outputs a dog list of all stored specimen.
    func List(c *echo.Context) error {
        // Note the use of models.Xyz
        var res := make([]models.Dog, 0) // A little trick to not return nil.
        err := store.FindAll("dogs", nil, &res) // Call manager to find all dogs.
        // handle error ...
    
        return c.JSON(200, res) // Output the dogs.
    }
    

    Finally you configure the app in main (or in a test):

    e := echo.New()
    dogs.Configure(e)
    // more apps
    
    e.Run(":8080")
    

    Note: for views, you can add them to project/apps/<name>/views folder and configure them the using the same function.

    Other

    Sometimes we also add a project/constants and a project/utils package.

    Here is what it looks like:

    Example of project structure

    Note that in above sample, templates are separated from apps, thats because its a placeholder, directory is empty.

    Hope it was useful. Greetings from México :D.

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(4条)

报告相同问题?

悬赏问题

  • ¥15 安卓adb backup备份应用数据失败
  • ¥15 eclipse运行项目时遇到的问题
  • ¥15 关于#c##的问题:最近需要用CAT工具Trados进行一些开发
  • ¥15 南大pa1 小游戏没有界面,并且报了如下错误,尝试过换显卡驱动,但是好像不行
  • ¥15 没有证书,nginx怎么反向代理到只能接受https的公网网站
  • ¥50 成都蓉城足球俱乐部小程序抢票
  • ¥15 yolov7训练自己的数据集
  • ¥15 esp8266与51单片机连接问题(标签-单片机|关键词-串口)(相关搜索:51单片机|单片机|测试代码)
  • ¥15 电力市场出清matlab yalmip kkt 双层优化问题
  • ¥30 ros小车路径规划实现不了,如何解决?(操作系统-ubuntu)