项目布局

最后更新于:2022-04-02 02:35:54

[TOC] ## 参考bilibili ``` . ├── app │ ├── admin │ │ └── foo/../ │ │ ├── cmd │ │ │ └── main.go │ │ ├── configs │ │ │ ├── http.conf │ │ │ ├── memcache.conf │ │ │ ├── mysql.con │ │ │ └── redis.con │ │ ├── internal │ │ │ ├── dao │ │ │ │ ├── dao.go │ │ │ │ └── user.go │ │ │ ├── model │ │ │ ├── server │ │ │ │ └── http │ │ │ │ └── router.go │ │ │ │ └── user.go │ │ │ └── service │ │ └── api │ │ └── api.proto │ ├── job │ │ └── foo/../ │ │ ├── cmd │ │ │ └── main.go │ │ ├── configs │ │ │ ├── http.conf │ │ │ ├── memcache.conf │ │ │ ├── mysql.con │ │ │ └── redis.con │ │ ├── internal │ │ │ ├── dao │ │ │ ├── model │ │ │ ├── server │ │ │ │ └── http │ │ │ └── service │ │ └── api │ │ └── api.proto │ ├── common │ └── service ├── library │ ├── cache │ │ ├── cache │ │ └── memcache │ ├── conf │ ├── container │ ├── database │ │ ├── orm │ │ ├── sql │ │ └── tidb │ ├── ecode │ │ └── pd │ ├── log │ ├── net │ │ ├── http │ │ ├── rpc │ │ └── strace │ └── text │ └── translate └── buid └── root.sh ``` ## 要点 1. library 是对第三方库的封装,或自己实现的基础库 2. app 中的调用的库尽量引用 library 中,而非外部库 3. app中的模块,可根据实际模块大小,来进行拆封到更细 4. 用gorm等工具并且不考虑数据库兼容问题时,推荐还是用原生sql,且只获取想要字段,并在 model 目录做结构体映射 ## 模块讲解 ### 对 foo 模块详解 #### dao dao 模块用来管理数据层的服务 如 dao.go在 ``` type Dao struct { db *sql.DB redis *redis.Pool redisExpire int32 mc *memcache.Pool mcExpire int32 } ``` user.go 对 sql的具体操作 ``` const ( _loadNotify = "SELECT n.id,topic.cluster,topic.topic,a.group,n.callback,n.concurrent,n.filter,n.mtime FROM notify AS n LEFT JOIN auth2 as a ON a.id=n.gid LEFT JOIN topic ON a.topic_id=topic.id WHERE n.state=1 AND n.zone=?" ) // LoadNotify load all notify config. func (d *Dao) LoadNotify(c context.Context, zone string) (ns []*model.Watcher, err error) { rows, err := d.db.Query(c, _loadNotify, zone) if err != nil { return } defer rows.Close() for rows.Next() { n := new(model.Watcher) if err = rows.Scan(&n.ID, &n.Cluster, &n.Topic, &n.Group, &n.Callback, &n.Concurrent, &n.Filter, &n.Mtime); err != nil { return } ns = append(ns, n) } return } ``` #### model 存放 dao 中获取到的model ``` type Watcher struct { ID int64 Cluster string Topic string Group string Offset string Callback string Filter bool Concurrent int // concurrent goroutine for sub. } ``` #### http http 用来存放与http 相关的服务 1. http 的路由,及handle 2. handle的具体内部实现放在 service 中 router.php ``` ... project := version.Group("/projects") { project.GET("/favorite", favoriteProjects) project.POST("/favorite/edit", editFavorite) project.GET("/common", queryCommonProjects) } ... ``` project.go ``` ... func favoriteProjects(ctx *bm.Context) { var ( req = &model.Pagination{} err error userName string ) if err = ctx.Bind(req); err != nil { ctx.JSON(nil, err) return } if userName, err = getUsername(ctx); err != nil { ctx.JSON(nil, err) return } // 最终的生成在 service 处理 ctx.JSON(srv.FavoriteProjects(ctx, req, userName)) } ... ``` service/foo.go ``` ... func (s *Service) FavoriteProjects(c context.Context, req *model.Pagination, userName string) (resp *model.FavoriteProjectsResp, err error) { // code } ... ``` #### service 1. 把所有的服务都挂载 service 中 2. 对 handle 的具体实现放入service 中 ``` type Service struct { c *conf.Config dao *dao.Dao transferChan *fanout.Fanout cron *cron.Cron } ``` ## 可以使用
';