pink-lady

module
v1.1.1 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Sep 20, 2019 License: Apache-2.0

README

pink-lady

proj-icon

Build Status Codacy Badge go report card codecov version-badge downloads license issues Say Thanks! PRs Welcome

The typically gin-based web application's organizational structure -> pink-lady.

The name comes from the Pink Lady which is a national standard cocktail with Gin as Base.

Skeleton code organization structure

> tree
.
├── app                                  // source code directory
│   ├── apis                            // write your apis at this directory
│   │   ├── demo                       // the demo apis
│   │   │   ├── label.go
│   │   │   ├── labeling.go
│   │   │   ├── labeling_test.go
│   │   │   ├── label_test.go
│   │   │   ├── object.go
│   │   │   └── object_test.go
│   │   ├── init.go                    // skeleton default api
│   │   ├── init_test.go
│   │   ├── routes.go                  // register your handler function on url in here
│   │   └── routes_test.go
│   ├── config.yaml                     // your custom configuration file
│   ├── config.yaml.example             // example configuration file
│   ├── docs                            // api docs generate by swag
│   │   ├── docs.go
│   │   └── swagger
│   │       ├── swagger.json
│   │       └── swagger.yaml
│   ├── main.go                         // main run a endless api server
│   ├── middleware                      // skeleton default middlewares
│   │   ├── errorhandler.go            // handle 404 500 to return JSON
│   │   ├── errorhandler_test.go
│   │   ├── ginlogrus.go               // logs use logrus and add custom fields
│   │   ├── ginlogrus_test.go
│   │   ├── init.go
│   │   ├── requestid.go               // set request id in header and logger
│   │   └── requestid_test.go
│   ├── models                          // write your models at here
│   │   ├── demo                       // the demo models
│   │   │   ├── label.go
│   │   │   └── object.go
│   │   ├── init.go                    // provide a base model
│   │   └── init_test.go
│   ├── router                          // gin router
│   │   ├── router.go                  // return router with middlewares
│   │   └── router_test.go
│   ├── services                        // write your business handler at here
│   │   ├── demo                       // the demo services
│   │   │   ├── label.go
│   │   │   ├── labeling.go
│   │   │   ├── labeling_test.go
│   │   │   ├── label_test.go
│   │   │   ├── object.go
│   │   │   └── object_test.go
│   │   ├── init.go
│   │   ├── init_test.go
│   │   └── retcode                    // write your business return code at here
│   │       ├── retcode.go
│   │       └── retcode_test.go
│   └── utils                           // add common utils at here
│       ├── endless.go                  // provide a graceful stop server
│       ├── gorequest.go                // provide a http client
│       ├── gorm.go                     // provide gorm db client
│       ├── gorm_test.go
│       ├── init.go
│       ├── jsontime.go                 // provide a custom format time field for json
│       ├── jsontime_test.go
│       ├── logrus.go                   // provide a logger
│       ├── logrus_test.go
│       ├── pagination.go               // provide a pagination function
│       ├── pagination_test.go
│       ├── redis.go                    // provide a redis client
│       ├── redis_test.go
│       ├── response                    // provide united json response functions
│       │   ├── response.go
│       │   └── response_test.go
│       ├── testing.go                  // provide GET/POST request function for testing
│       ├── viper.go                    // provide configuration parser
│       └── viper_test.go
├── CODE_OF_CONDUCT.md
├── go.mod                               // go mod file
├── go.sum                               // go mod file
├── LICENSE
├── misc                                 // write your tool scripts at here
│   ├── gen_apidoc.sh                   // gen api docs
│   ├── new-project.sh                  // create new project using pink-lady
│   ├── pinklady.png                    // logo
│   ├── pre-push.githook                // a git pe-push hook for run test when push
│   ├── README.md
│   ├── release.sh                      // a tool for release the binary app
│   ├── sql                             // save your sqls at there
│   │   └── README.md
│   └── supervisor.conf
└── README.md

Develop requirements

  • [Go >= 1.11] It requires Go 1.11 or newer to use go mod and run testing coverage.
  • [swaggo/swag] Automatically generate RESTful API documentation with Swagger 2.0 for Go.
  • [pilu/fresh] Build and (re)start go web apps after saving/creating/deleting source files.

You maybe need to install them. For installation, please refer to their home page.

Skeleton dependencies

Feature

  • Clear code organization.
  • Validation of production environment.
  • Flexible and rich configuration, easy to configure for server, log, database, redis and sentry.
  • Detailed and leveled log, easy to log gin request log with requestid and orm sql log.
  • Support multiple database ORM such as sqlite3, mysql, postgresql and sqlserver.
  • Support redis single client, sentinel client and cluster client.
  • Support sentry for collecting panic logs.
  • Provide a graceful restart/stop server.
  • Integration of gorequest, pagination, functions for testing and other common tools.
  • Provide functions to respond unified JSON structrue with code, message, data fields.
  • Provide easy-to-use business return code.
  • Gin router support handle 404/500 requests as a unified JSON structure.
  • Support auto generating the swagger API docs by comments
  • Provide a release.sh tool for releasing binary in misc directory.

How to build web API server with pink-lady

First, Run the script to create your new project:

source <(curl -s https://raw.githubusercontent.com/axiaoxin/pink-lady/master/misc/new-project.sh)

You will get the project skeleton, then you can do coding.

You also can create project skeleton manually:

Clone the pink-lady into your gopath and install dependebcies:

cd $(go env GOPATH)/src
git clone git@github.com:axiaoxin/pink-lady.git
cd pink-lady

if you want to change the project path or name, you must change the import path too:

# replace project name
mv github.com/axiaoxin/pink-lady ${projname}
cd ${projname}
sed -i "s|github.com/axiaoxin/pink-lady|${projname}|g"  `grep "github.com/axiaoxin/pink-lady" --include *.go --include go.* -rl .`

# init git
rm -rf .git
git init
git add .
git commit -m "init project from pink-lady"

# remove demo
rm -rf app/docs
rm -rf app/apis/demo
rm -rf app/services/demo
rm -rf app/models/demo
sed -i "/demo routes start/,/demo routes end/d" app/apis/routes.go

Second, Write your API in apis directory, you can create a file or a subdirectory as a package to save your gin API handler function, then register the handlers on url in apis/routes.go like the default ping API

Third, Run develop server in app directory:

cd app
cp config.yaml.example config.yaml
go test ./...
go run main.go

Fourth, Release your API server, run misc/release.sh will build a binary app in build directory if your tests all pass, and bump version, update api docs and make a git commit and add a tag with the version

cd misc
./release.sh

If you wrote swag style comments you can generate the API docs in app directory manually:

cd app
swag init -g apis/init.go

You can test your API by curl or swagger API docs:http://pink-lady:4869/x/apidocs/index.html, sure, you need to configure a host of pink-lady for your server

Develop suggestions

  • You should put your API handler functions in app/apis as a single file or a package, then register the handlers in app/apis/routes.go
  • Add your middleware in app/middleware, use it by adding to app/router/router.go
  • Define the database model in app/models by embed BaseModel in app/models/init.go
  • Write reusable business code in app/services as single file or a package
  • Define the return codes in app/services/retcode/retcode.go
  • Add generic business independent tool type code in app/utils
  • Add tool scripts etc in misc
  • Write unit tests and doc for functions
  • Integrate Travis, code quality, goreport and codecov
  • A convinent way to dynamic reload the server when code changing, you can use fresh to run server in app directory
  • There is a demo in pink-lady, a api service for labeling object with label, you can delete it in apis/demo services/demo models/demo
  • If you want to log with requestid, you should use utils.CtxLogger(c) to get a logger with requestid

Directories

Path Synopsis
app
apis
Package apis save the web api code init.go define init() function and default system api handlers save you handle functions routes.go register handle function on url WAY TO ADD YOUR NEW API: create code file or package according to you business logic, let structure be modularized write the gin handlerFunc code like the Ping() in the file you should extract the common business logic handle functions into services package database model should be defined in models package by modularized general tool functions should be defined in utils package by modularized you can record log by utils.Logger and get config by viper you can return unified json struct by utils/response package the new return code should be defined in services/retcode package when you finish the handlerFunc you need to register it on a url in routes.go that's all.
Package apis save the web api code init.go define init() function and default system api handlers save you handle functions routes.go register handle function on url WAY TO ADD YOUR NEW API: create code file or package according to you business logic, let structure be modularized write the gin handlerFunc code like the Ping() in the file you should extract the common business logic handle functions into services package database model should be defined in models package by modularized general tool functions should be defined in utils package by modularized you can record log by utils.Logger and get config by viper you can return unified json struct by utils/response package the new return code should be defined in services/retcode package when you finish the handlerFunc you need to register it on a url in routes.go that's all.
middleware
Package middleware save your custom middlewares at here
Package middleware save your custom middlewares at here
models
Package models save database models define your database models in the package
Package models save database models define your database models in the package
router
Package router provide a function to setup gin router without routes
Package router provide a function to setup gin router without routes
services
Package services save common business logic code
Package services save common business logic code
services/retcode
Package retcode define all api return code at here
Package retcode define all api return code at here
utils
Package utils save the package of third party package tools and the general tool code written by yourself write your general tool in the package
Package utils save the package of third party package tools and the general tool code written by yourself write your general tool in the package

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL