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 素材场景中光线烘焙后灯光失效
  • ¥15 请教一下各位,为什么我这个没有实现模拟点击
  • ¥15 执行 virtuoso 命令后,界面没有,cadence 启动不起来
  • ¥50 comfyui下连接animatediff节点生成视频质量非常差的原因
  • ¥20 有关区间dp的问题求解
  • ¥15 多电路系统共用电源的串扰问题
  • ¥15 slam rangenet++配置
  • ¥15 有没有研究水声通信方面的帮我改俩matlab代码
  • ¥15 ubuntu子系统密码忘记
  • ¥15 保护模式-系统加载-段寄存器