[feat] add pkgs, dockerfile, makefile
This commit is contained in:
@@ -1,6 +1,7 @@
|
||||
package args
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"os"
|
||||
|
||||
"git.trj.tw/golang/argparse"
|
||||
@@ -26,3 +27,10 @@ func Parse() error {
|
||||
|
||||
return parser.Parse(os.Args)
|
||||
}
|
||||
|
||||
func Get() *Args {
|
||||
if a == nil {
|
||||
panic(errors.New("arguments not init"))
|
||||
}
|
||||
return a
|
||||
}
|
||||
|
||||
@@ -17,9 +17,17 @@ type Database struct {
|
||||
IdleConn uint `yaml:"idle_conn" env:"DB_IDLE_CONN" default:"2"`
|
||||
}
|
||||
|
||||
// Redis connect setting
|
||||
type Redis struct {
|
||||
Host string `yaml:"host" env:"REDIS_HOST" default:"localhost"`
|
||||
Port int `yaml:"port" env:"REDIS_PORT" default:"6379"`
|
||||
Prefix string `yaml:"prefix" env:"REDIS_PREFIX"`
|
||||
}
|
||||
|
||||
type Config struct {
|
||||
Server Server `yaml:"server"`
|
||||
Database Database `yaml:"database"`
|
||||
Redis Redis `yaml:"redis"`
|
||||
}
|
||||
|
||||
var c *Config
|
||||
|
||||
@@ -0,0 +1,75 @@
|
||||
package context
|
||||
|
||||
import (
|
||||
"context"
|
||||
"go-api/pkg/response"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
)
|
||||
|
||||
type C struct {
|
||||
*gin.Context
|
||||
}
|
||||
|
||||
type CustomHandler func(c *C)
|
||||
|
||||
func PatchContext(handler CustomHandler) gin.HandlerFunc {
|
||||
return func(ctx *gin.Context) {
|
||||
c := &C{
|
||||
Context: ctx,
|
||||
}
|
||||
handler(c)
|
||||
}
|
||||
}
|
||||
|
||||
func (c *C) getContext() context.Context {
|
||||
return c.Request.Context()
|
||||
}
|
||||
|
||||
// Success
|
||||
// send success body to client
|
||||
func (c *C) Success(i ...interface{}) {
|
||||
r := response.Get(response.RespSuccess)
|
||||
|
||||
var resp interface{} = r.Body
|
||||
if len(i) > 0 {
|
||||
resp = i[0]
|
||||
}
|
||||
|
||||
c.AbortWithStatusJSON(r.Status, resp)
|
||||
}
|
||||
|
||||
func (c *C) DataFormat(code ...response.MessageCode) {
|
||||
r := response.Get(response.RespDataFormat, code...)
|
||||
c.AbortWithStatusJSON(r.Status, r.Body)
|
||||
}
|
||||
|
||||
func (c *C) NotFound(code ...response.MessageCode) {
|
||||
r := response.Get(response.RespNotFound, code...)
|
||||
c.AbortWithStatusJSON(r.Status, r.Body)
|
||||
}
|
||||
|
||||
func (c *C) Forbidden(code ...response.MessageCode) {
|
||||
r := response.Get(response.RespNotFound, code...)
|
||||
c.AbortWithStatusJSON(r.Status, r.Body)
|
||||
}
|
||||
|
||||
func (c *C) ServerError(code ...response.MessageCode) {
|
||||
r := response.Get(response.RespInternalError, code...)
|
||||
c.AbortWithStatusJSON(r.Status, r.Body)
|
||||
}
|
||||
|
||||
func (c *C) CustomResp(rt response.RespType, code response.MessageCode, data ...interface{}) {
|
||||
r := response.Get(rt)
|
||||
|
||||
if code != r.Body.MessageCode {
|
||||
r.Body.MessageCode, r.Body.Message = response.GetCodeMessage(code)
|
||||
}
|
||||
|
||||
var resp interface{} = r.Body
|
||||
if len(data) > 0 {
|
||||
resp = data[0]
|
||||
}
|
||||
|
||||
c.AbortWithStatusJSON(r.Status, resp)
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
package errors
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"go-api/pkg/response"
|
||||
)
|
||||
|
||||
var (
|
||||
ErrDataFormat = New(response.RespDataFormat)
|
||||
ErrUnauthorized = New(response.RespUnauthorized)
|
||||
ErrNotFound = New(response.RespNotFound)
|
||||
ErrInternalError = New(response.RespInternalError)
|
||||
)
|
||||
|
||||
type APIError struct {
|
||||
code *response.MessageCode
|
||||
status response.RespType
|
||||
message string
|
||||
}
|
||||
|
||||
func (e *APIError) Error() string {
|
||||
s := fmt.Sprintf("Status: %s, Message: %s", e.status, e.message)
|
||||
if e.code != nil {
|
||||
c, m := response.GetCodeMessage(*e.code)
|
||||
s = fmt.Sprintf("%s, Code: %d, CodeMessage: %s", s, c, m)
|
||||
}
|
||||
return s
|
||||
}
|
||||
|
||||
func New(status response.RespType, code ...response.MessageCode) *APIError {
|
||||
e := &APIError{
|
||||
status: status,
|
||||
}
|
||||
|
||||
if len(code) > 0 {
|
||||
e.code = &code[0]
|
||||
}
|
||||
return e
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
package redis
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/go-redis/redis"
|
||||
)
|
||||
|
||||
const (
|
||||
KeyToken = "91-token:%s"
|
||||
)
|
||||
|
||||
type Redis struct {
|
||||
*redis.Client
|
||||
prefix string
|
||||
}
|
||||
|
||||
var r *Redis
|
||||
|
||||
// Init redis client
|
||||
func Init(port int, host, prefix string) error {
|
||||
r = &Redis{prefix: prefix}
|
||||
r.Client = redis.NewClient(&redis.Options{
|
||||
Addr: fmt.Sprintf("%s:%d", host, port),
|
||||
})
|
||||
|
||||
if _, err := r.Ping().Result(); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// Key combine prefix to key
|
||||
func (x *Redis) Key(key string) string {
|
||||
if len(x.prefix) > 0 {
|
||||
return fmt.Sprintf("%s:%s", x.prefix, key)
|
||||
}
|
||||
return key
|
||||
}
|
||||
@@ -0,0 +1,44 @@
|
||||
package response
|
||||
|
||||
type MessageCode int
|
||||
|
||||
const (
|
||||
// HTTP Default Message
|
||||
CodeSuccess MessageCode = 1000
|
||||
CodeCreated MessageCode = 1001
|
||||
CodeAccepted MessageCode = 1002
|
||||
CodeNoContent MessageCode = 1003
|
||||
CodeRedirect MessageCode = 1004
|
||||
CodeDataFormat MessageCode = 1005
|
||||
CodeUnauthorized MessageCode = 1006
|
||||
CodeForbidden MessageCode = 1007
|
||||
CodeNotFound MessageCode = 1008
|
||||
CodeInternalError MessageCode = 1009
|
||||
|
||||
// Custom Message
|
||||
)
|
||||
|
||||
var code map[MessageCode]string
|
||||
|
||||
func init() {
|
||||
code = map[MessageCode]string{
|
||||
CodeSuccess: "Success",
|
||||
CodeCreated: "Created",
|
||||
CodeAccepted: "Accepted",
|
||||
CodeNoContent: "No Content",
|
||||
CodeRedirect: "Moved Permanently",
|
||||
CodeDataFormat: "Data Format Error",
|
||||
CodeUnauthorized: "Unauhorized",
|
||||
CodeForbidden: "Forbidden",
|
||||
CodeNotFound: "Not Found",
|
||||
CodeInternalError: "Internal Error",
|
||||
}
|
||||
}
|
||||
|
||||
func GetCodeMessage(c MessageCode) (MessageCode, string) {
|
||||
if r, ok := code[c]; ok {
|
||||
return c, r
|
||||
}
|
||||
|
||||
return c, ""
|
||||
}
|
||||
@@ -0,0 +1,81 @@
|
||||
package response
|
||||
|
||||
type RespType string
|
||||
|
||||
const (
|
||||
RespSuccess RespType = "success"
|
||||
RespCreated RespType = "created"
|
||||
RespAccepted RespType = "accepted"
|
||||
RespNoContent RespType = "noContent"
|
||||
RespRedirect RespType = "redirect"
|
||||
RespDataFormat RespType = "dataFormat"
|
||||
RespUnauthorized RespType = "unauthorized"
|
||||
RespForbidden RespType = "forbidden"
|
||||
RespNotFound RespType = "notFound"
|
||||
RespInternalError RespType = "internalError"
|
||||
)
|
||||
|
||||
// swagger:model defResponse
|
||||
type RespBody struct {
|
||||
MessageCode MessageCode `json:"messageCode"`
|
||||
Message string `json:"message"`
|
||||
}
|
||||
|
||||
// swagger:response genericResponse
|
||||
type Resp struct {
|
||||
// in: body
|
||||
Body RespBody
|
||||
Status int
|
||||
}
|
||||
|
||||
func Get(key RespType, c ...MessageCode) Resp {
|
||||
r := Resp{Body: RespBody{}}
|
||||
|
||||
switch key {
|
||||
case RespSuccess:
|
||||
r.Status = 200
|
||||
r.Body.MessageCode, r.Body.Message = GetCodeMessage(CodeSuccess)
|
||||
break
|
||||
case RespCreated:
|
||||
r.Status = 201
|
||||
r.Body.MessageCode, r.Body.Message = GetCodeMessage(CodeCreated)
|
||||
break
|
||||
case RespAccepted:
|
||||
r.Status = 202
|
||||
r.Body.MessageCode, r.Body.Message = GetCodeMessage(CodeAccepted)
|
||||
break
|
||||
case RespNoContent:
|
||||
r.Status = 204
|
||||
r.Body.MessageCode, r.Body.Message = GetCodeMessage(CodeNoContent)
|
||||
break
|
||||
case RespRedirect:
|
||||
r.Status = 301
|
||||
r.Body.MessageCode, r.Body.Message = GetCodeMessage(CodeRedirect)
|
||||
break
|
||||
case RespDataFormat:
|
||||
r.Status = 400
|
||||
r.Body.MessageCode, r.Body.Message = GetCodeMessage(CodeDataFormat)
|
||||
break
|
||||
case RespUnauthorized:
|
||||
r.Status = 401
|
||||
r.Body.MessageCode, r.Body.Message = GetCodeMessage(CodeUnauthorized)
|
||||
break
|
||||
case RespForbidden:
|
||||
r.Status = 403
|
||||
r.Body.MessageCode, r.Body.Message = GetCodeMessage(CodeForbidden)
|
||||
break
|
||||
case RespNotFound:
|
||||
r.Status = 404
|
||||
r.Body.MessageCode, r.Body.Message = GetCodeMessage(CodeNotFound)
|
||||
break
|
||||
default:
|
||||
r.Status = 500
|
||||
r.Body.MessageCode, r.Body.Message = GetCodeMessage(CodeInternalError)
|
||||
}
|
||||
|
||||
if len(c) > 0 {
|
||||
r.Body.MessageCode, r.Body.Message = GetCodeMessage(c[0])
|
||||
}
|
||||
|
||||
return r
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
// Package swagger api document
|
||||
//
|
||||
// Terms Of Services:
|
||||
//
|
||||
// there are no TOS
|
||||
//
|
||||
// Schemes: http, https
|
||||
// Host localhost
|
||||
// BasePath: /
|
||||
// Version: 0.0.0
|
||||
//
|
||||
// Consumes:
|
||||
// - application/json
|
||||
// Produces:
|
||||
// - application/json
|
||||
//
|
||||
// swagger:meta
|
||||
package swagger
|
||||
@@ -0,0 +1,20 @@
|
||||
package version
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"runtime"
|
||||
)
|
||||
|
||||
var (
|
||||
Version string
|
||||
BuildDate string
|
||||
)
|
||||
|
||||
func PrintCliVersion() string {
|
||||
return fmt.Sprintf(
|
||||
"version: %s, built on %s, %s",
|
||||
Version,
|
||||
BuildDate,
|
||||
runtime.Version(),
|
||||
)
|
||||
}
|
||||
Reference in New Issue
Block a user