The Golang server template below was prepared to transfer knowledge within our team. The main goal of the template, in addition to training, is to reduce the time for prototyping small server tasks on Go.
The first part of the template was devoted to the HTTP server:
- Configuring an HTTP server through the command line and configuration file
- Configure TLS HTTP server settings
- router setup and registration of HTTP and prof-handlers
- setting up HTTP traffic logging, HTTP error logging
- HTTP Basic and MS AD Authentication, JSON Web Token
- starting the server with the expectation of returning to the error channel
- using context to stop the server and related services correctly
- custom error handling and custom logging
- code assembly with implementation of version, build date and commit
The second part of the template is devoted to prototyping the REST API.
The link to the project repository remains the same.

In the course of testing the template at the stand , the following results were obtained .
- in direct reading mode from PostgreSQL - up to 16,000 [get / sec], concurrency 1024, median 60 [ms]. Each Get requests data from two tables with a total size of 360,000,000 rows. JSON size is 1800 bytes.
- 100 000 β 120 000 [get/sec], oncurrency 1024, 2 [ms]. Transfer rate 200-250 [MB/sec]
- PostgreSQL β 10 000 [insert/sec].
 - ,
- Marshal / Unmarshal JSON
 
- SQLXX
 
- DB
 
- JSON
 - Marshal / Unmarshal JSON
- Unmarshal JSON
- JSON
 
- HTTP
 
 
1.
.
- Model :
 - Marshal / Unmarshal JSON
- -
 
- SQLXX :
 
- DB :
 
- JSON JSON :
 - Marshal / Unmarshal JSON
- JSON
 
- HTTP HTTP :
 - HTTP
- HTTP
- (basic, MS AD, ...)
- token
- (body)
- (header)
- HSTS Strict-Transport-Security
- Content-Type (response)
- HTTP
- (header)
- defer recovery panic
 
REST API : FaaS, , gRPC.
2 Model
2.1. ,
, "Department" "Employee". .
, JOSN .
(-).
type Dept struct {
    Deptno int         `db:"deptno" json:"deptNumber" validate:"required"`
    Dname  string      `db:"dname" json:"deptName" validate:"required"`
    Loc    null.String `db:"loc" json:"deptLocation,nullempty"`
    Emps   []*Emp      `json:"emps,omitempty"`
}
type Emp struct {
    Empno    int         `db:"empno" json:"empNo" validate:"required"`
    Ename    null.String `db:"ename" json:"empName,nullempty"`
    Job      null.String `db:"job" json:"job,nullempty"`
    Mgr      null.Int    `db:"mgr" json:"mgr,omitempty"`
    Hiredate null.String `db:"hiredate" json:"hiredate,nullempty"`
    Sal      null.Int    `db:"sal" json:"sal,nullempty" validate:"gte=0"`
    Comm     null.Int    `db:"comm" json:"comm,nullempty" validate:"gte=0"`
    Deptno   null.Int    `db:"deptno" json:"deptNumber,nullempty"`
}
.
( ).
, , - (, ). "" .
REST API , : Get, Create, Update.
context.Context β " ".
, , , , , . sync.Pool.
type DeptService interface {
    GetDept(ctx context.Context, out *Dept) (bool, error)
    GetDeptsPK(ctx context.Context, out *DeptPKs) error
    CreateDept(ctx context.Context, in *Dept, out *Dept) error
    UpdateDept(ctx context.Context, in *Dept, out *Dept)  (bool, error)
}
type EmpService interface {
    GetEmp(ctx context.Context, out *Emp) (bool, error)
    GetEmpsByDept(ctx context.Context, in *Dept, out *EmpSlice) error
    CreateEmp(ctx context.Context, in *Emp, out *Emp) error
    UpdateEmp(ctx context.Context, in *Emp, out *Emp)  (bool, error)
}
2.1.2
IBM MQ.
type Request struct {
    QObject               string 
    QueueName             string 
    QueueOptions          int32  
    QueueWaitInterval     int    
    MsgIdHex              string 
    CorrelIdHex           string 
    MesFormat             string 
    MesSyncpoint          int32  
    MesOptions            int32  
    BrowseOptions         int32  
    Bufsize               int    
    Buf                   []byte `json:"-"` 
}
type Response struct {
    QObject      string 
    QueueName    string 
    MsgId        []byte 
    MsgIdHex     string 
    CorrelId     []byte 
    CorrelIdHex  string 
    PutDate      string 
    PutTime      string 
    DataLen      int    
    ErrCode      string 
    ErrMes       string 
    ErrTrace     string 
    CauseErrCode string 
    CauseErrMes  string 
    Buf          []byte 
}
IBM MQ.
type QueueService interface {
    OpenQueue(ctx context.Context, req *Request, resp *Response) error
    CloseQueue(ctx context.Context, req *Request, resp *Response) error
    BrowseMessage(ctx context.Context, req *Request, resp *Response) error
    BrowseFirstMessage(ctx context.Context, req *Request, resp *Response) error
    BrowseNextMessage(ctx context.Context, req *Request, resp *Response) error
    BrowseUnderMessage(ctx context.Context, req *Request, resp *Response) error
    GetMessage(ctx context.Context, req *Request, resp *Response) error
    DeleteUnderMessage(ctx context.Context, req *Request, resp *Response) error
    PutMessage(ctx context.Context, req *Request, resp *Response) error
    RegisterCallback(ctx context.Context, req *Request, resp *Response) error
    DeregisterCallback(ctx context.Context, req *Request, resp *Response) error
}
2.2.
, :
- β , . , "" > 0, "" not null.
- β , " " >= " "
- () β , " " >= " "
- β , (PK, UK), .
- β , (FK), .
- β , .
1, 2 3 . 4, 5, 6 , , .
.
, , , .
- .
- " API". , DML . , API. , Oracle , API.
- (View API), , .
- Instead of Trigger DML API.
, β DML . ( Oracle ). API, .
.
, 1, 2 3 JSON .
3 1, 2 3 gopkg.in/go-playground/validator.
4 (PK, UK).
5 6 .
2.3.
REST API (JSON->Model->DB) (). , , JSON . API, (GC). ( GC).
GC β sync.Pool. . β sync.Pool.
, β sync.Pool, , , , .
sync.Pool :
Dept
var deptsPool = sync.Pool{
    New: func() interface{} { return new(Dept) },
}
func GetDept() *Dept {
    p := deptsPool.Get().(*Dept)
    p.Reset()
    return p
}
func PutDept(p *Dept, isCascad bool) {
    if p != nil {
        PutEmpSlice(p.Emps, isCascad)
        p.Emps = nil
        deptsPool.Put(p)
    }
}
func (p *Dept) Reset() {
    p.Deptno = 0
    p.Dname = ""
    p.Loc.String = ""
    p.Loc.Valid = false
    if p.Emps != nil {
        EmpSlice(p.Emps).Reset()
    }
    p.Emps = nil
}
type EmpSlice []*Emp
func PutEmpSlice(p EmpSlice) {
    if p != nil {
        for i := range p {
            p[i] = nil 
        }
        p = p[:0] 
        empSlicePool.Put(p)
    }
}
, , 1000000 Get , 500 . .
, sync.Pool CPU, sync.Pool .
dept emp , .
2.4. Marshal / Unmarshal JSON
encoding/json .
:
. .
:
github.com/mailru/easyjson.
, , / JSON .
type Dept struct {
    Deptno int         `db:"deptno" json:"deptNumber" validate:"required"`
    Dname  string      `db:"dname" json:"deptName" validate:"required"`
    Loc    null.String `db:"loc" json:"deptLocation,nullempty"`
    Emps   []*Emp      `json:"emps,omitempty"`
}
, easyjson NULL , gopkg.in/guregu/null.v4. , NULL , , "Loc null.String" "Loc sql.NullString".
.
easyjson model.go
Marshal / Unmarshal , JSON.
3. SQLXX
SQLXX :
- , , Listen/notify PostgreSQL (jackc/pgx/stdlib lib/pq)
, .
, , SQL .
httpserver/sqlxx jmoiron/sqlx.
type DB struct {
    *sqlx.DB
    cfg     *Config
    sqlStms SQLStms 
}
type Tx struct {
    *sqlx.Tx
}
, , jmoiron/sqlx, , jackc/pgx.
3.1.
jmoiron/sqlx , : Beginx, Rollback, Commit, Select, Get, Exec.
.
INFO trace. , , , , .
func Commit(reqID uint64, tx *Tx) (myerr error) {
    
    defer func() {
        r := recover()
        if r != nil {
            msg := "PostgreSQL recover from panic: commit transaction: reqID"
            switch t := r.(type) {
            case string:
                myerr = myerror.New("4008", msg, reqID, t).PrintfInfo()
            case error:
                myerr = myerror.WithCause("4006", msg, t, reqID).PrintfInfo()
            default:
                myerr = myerror.New("4006", msg, reqID).PrintfInfo()
            }
        }
    }()
    
    if tx == nil {
        return myerror.New("4004", "Transaction is not defined: reqID", reqID).PrintfInfo()
    }
    if err := tx.Commit(); err != nil {
        return myerror.WithCause("4008", "Error commit the transaction: reqID", err, reqID).PrintfInfo()
    }
    return nil
}
interface{}, , , , .
func Select(reqID uint64, tx *Tx, sqlStm *SQLStm, dest interface{}, args ...interface{}) (myerr error) {
    if dest != nil && !reflect.ValueOf(dest).IsNil() {
        
    }
    return myerror.New("4400", "Incorrect call - nil dest interface{} pointer: reqID", reqID).PrintfInfo()
}
reflect.ValueOf(in).IsNil() , .
3.2.
. .
type Config struct {
    ConnectString   string 
    Host            string 
    Port            string 
    Dbname          string 
    SslMode         string 
    User            string 
    Pass            string 
    ConnMaxLifetime int    
    MaxOpenConns    int    
    MaxIdleConns    int    
    DriverName      string 
}
3.3. SQL
SQLXX SQL interface{}.
, SQL .
SQLXX SQL . SQL , , ( SQL ).
type SQLStm struct {
    Text      string     
    Stmt      *sqlx.Stmt 
    IsPrepare bool       
}
type SQLStms map[string]*SQLStm
4. DB
DB :
4.1. , SQL
, (-) :
- (PK) β API. GUID, , BTree .
- (UK), , " ". UK .
- (FK) PK. (FK), FK API . FK.
dept emp, , β .
DB SQL .
SQL : "GetDept", "GetDeptUK", "DeptExists" .. , SQL.
, SQL :
- PK, , "GetDept"
- UK, , "GetDeptUK"
- PK UK, , "DeptExists"
, View API. SQL REST API . .
service.SQLStms = map[string]*sql.SQLStm{
    "GetDept":         &sql.SQLStm{"SELECT deptno, dname, loc FROM dept WHERE deptno = $1", nil, true},
    "GetDeptUK":       &sql.SQLStm{"SELECT deptno, dname, loc FROM dept WHERE deptno = $1", nil, true},
    "DeptExists":      &sql.SQLStm{"SELECT 1 FROM dept WHERE deptno = $1", nil, true},
    "GetDepts":        &sql.SQLStm{"SELECT deptno, dname, loc FROM dept", nil, true},
    "GetDeptsPK":      &sql.SQLStm{"SELECT deptno FROM dept", nil, true},
    "CreateDept":      &sql.SQLStm{"INSERT INTO dept (deptno, dname, loc) VALUES (:deptno, :dname, :loc)", nil, false},
    "UpdateDept":      &sql.SQLStm{"UPDATE dept SET dname = :dname, loc = :loc WHERE deptno = :deptno", nil, false},
    "EmpExists":       &sql.SQLStm{"SELECT 1 FROM emp WHERE empno = $1", nil, true},
    "GetEmp":          &sql.SQLStm{"SELECT empno, ename, job, mgr, hiredate, sal, comm, deptno FROM emp WHERE empno = $1", nil, true},
    "GetEmpUK":        &sql.SQLStm{"SELECT empno, ename, job, mgr, hiredate, sal, comm, deptno FROM emp WHERE empno = $1", nil, true},
    "GetEmpsByDept":   &sql.SQLStm{"SELECT empno, ename, job, mgr, hiredate, sal, comm, deptno FROM emp WHERE deptno = $1", nil, true},
    "GetEmpsPKByDept": &sql.SQLStm{"SELECT empno FROM emp WHERE deptno = $1", nil, true},
    "CreateEmp":       &sql.SQLStm{"INSERT INTO emp (empno, ename, job, mgr, hiredate, sal, comm, deptno) VALUES (:empno, :ename, :job, :mgr, :hiredate, :sal, :comm, :deptno)", nil, false},
    "UpdateEmp":       &sql.SQLStm{"UPDATE emp SET empno = :empno, ename = :ename, job = :job, mgr = :mgr, hiredate = :hiredate, sal = :sal, comm = :comm, deptno = :deptno WHERE empno = :empno", nil, false},
}
, SQL "".
4.2.
:
4.2.1 Get
Get . , .
func (s *Service) getDept(ctx context.Context, tx *mysql.Tx, out *model.Dept) (exists bool, myerr error) {
    
    if exists, myerr = s.db.Get(reqID, tx, "GetDept", out, out.Deptno); myerr != nil {
        return false, myerr
    }
    
    if exists {
        outEmps := model.GetEmpSlice() 
        if myerr = s.getEmpsByDept(ctx, tx, out, &outEmps); myerr != nil {
            return false, myerr
        }
        out.Emps = outEmps 
    }
    return exists, nil
}
Get .
func (s *Service) GetDept(ctx context.Context, out *model.Dept) (exists bool, myerr error) {
    return s.getDept(ctx, nil, out)
}
4.2.2 Create
Create :
- newDept, model.GetDept(). , .
- . UK ( Dept ).
 - Get(reqID, tx, "DeptExists", &foo, in.Deptno), β UK. args ...interface{}, .
- , β . .
 
- PK
 - . , SQL / 1 . , .
- API, , / PK, , Get(reqID, tx, "GetDeptUK", newDept, in.Deptno) UK.
 
 - , FK newEmp.Deptno = null.Int{sql.NullInt64{int64(newDept.Deptno), true}} createEmp(ctx, tx, newEmp, nil).
- , .
 
- β PK
 - β JSON .
- HTTP .
- , nil out.
 
func (s *Service) createDept(ctx context.Context, tx *mysql.Tx, in *model.Dept, out *model.Dept) (myerr error) {
    newDept := model.GetDept()         
    defer model.PutDept(newDept, true) 
    { 
        var foo int
        exists, myerr := s.db.Get(reqID, tx, "DeptExists", &foo, in.Deptno)
        if myerr != nil {
            return myerr
        }
        if exists {
            return myerror.New("4004", "Error create - row already exists: reqID, Deptno", reqID, in.Deptno).PrintfInfo()
        }
    } 
    { 
        rows, myerr := s.db.Exec(reqID, tx, "CreateDept", in)
        if myerr != nil {
            return myerr
        }
        
        if rows != 1 {
            return myerror.New("4004", "Error create: reqID, Deptno, rows", reqID, in.Deptno, rows).PrintfInfo()
        }
        
        
        exists, myerr := s.db.Get(reqID, tx, "GetDeptUK", newDept, in.Deptno)
        if myerr != nil {
            return myerr
        }
        if !exists {
            return myerror.New("4004", "Row does not exists after creating: reqID, Deptno", reqID, in.Deptno).PrintfInfo()
        }
    } 
    { 
        if in.Emps != nil {
            for _, newEmp := range in.Emps {
                
                newEmp.Deptno = null.Int{sql.NullInt64{int64(newDept.Deptno), true}}
                
                if myerr = s.createEmp(ctx, tx, newEmp, nil); myerr != nil {
                    return myerr
                }
            }
        }
    } 
    
    if out != nil {
        out.Deptno = newDept.Deptno 
        exists, myerr := s.getDept(ctx, tx, out)
        if myerr != nil {
            return myerr
        }
        
        if !exists {
            return myerror.New("4004", "Row does not exists after updating: reqID, PK", reqID, in.Deptno).PrintfInfo()
        }
    }
    return nil
}
Create :
func (s *Service) CreateDept(ctx context.Context, in *model.Dept, out *model.Dept) (myerr error) {
    var tx *mysql.Tx
    reqID := myctx.FromContextRequestID(ctx) 
    
    if tx, myerr = s.db.Beginx(reqID); myerr != nil {
        return myerr
    }
    
    if myerr = s.createDept(ctx, tx, in, out); myerr != nil {
        _ = s.db.Rollback(reqID, tx)
        return myerr
    }
    
    return s.db.Commit(reqID, tx)
}
4.2.3 Update
Update :
- oldDept newDept, .
- PK.
 
 
 - . , SQL 1 .
- API, , / , , P Get(reqID, tx, "GetDept", newDept, in.Deptno).
 
 - , FK updateEmp(ctx, tx, inEmp, nil).
- ,
 
- β PK
func (s *Service) updateDept(ctx context.Context, tx *mysql.Tx, in *model.Dept, out *model.Dept) (exists bool, myerr error) {
    oldDept := model.GetDept()         
    defer model.PutDept(oldDept, true) 
    newDept := model.GetDept()         
    defer model.PutDept(newDept, true) 
    { 
        oldDept.Deptno = in.Deptno 
        if exists, myerr = s.getDept(ctx, tx, oldDept); myerr != nil {
            return false, myerr
        }
        if !exists {
            mylog.PrintfDebugMsg("Row does not exists: reqID, PK", reqID, in.Deptno)
            return false, nil
        }
    } 
    { 
        
        
        if oldDept.Deptno != in.Deptno {
            var foo int
            exists, myerr := s.db.Get(reqID, tx, "DeptExists", &foo, in.Deptno)
            if myerr != nil {
                return false, myerr
            }
            if exists {
                return false, myerror.New("4004", "Error update - row with UK already exists: reqID, Deptno", reqID, in.Deptno).PrintfInfo()
            }
        }
    } 
    { 
        rows, myerr := s.db.Exec(reqID, tx, "UpdateDept", in)
        if myerr != nil {
            return false, myerr
        }
        
        if rows != 1 {
            return false, myerror.New("4004", "Error update: reqID, Deptno, rows", reqID, in.Deptno, rows).PrintfInfo()
        }
        
        exists, myerr := s.db.Get(reqID, tx, "GetDept", newDept, in.Deptno)
        if myerr != nil {
            return false, myerr
        }
        if !exists {
            return false, myerror.New("4004", "Row does not exists after creating: reqID, PK", reqID, in.Deptno).PrintfInfo()
        }
    } 
    { 
        if in.Emps != nil {
            for _, inEmp := range in.Emps {
                
                inEmp.Deptno = null.Int{sql.NullInt64{int64(in.Deptno), true}}
                
                if exists, myerr = s.updateEmp(ctx, tx, inEmp, nil); myerr != nil {
                    return false, myerr
                }
                
                if !exists {
                    if myerr = s.createEmp(ctx, tx, inEmp, nil); myerr != nil {
                        return false, myerr
                    }
                }
            }
        }
    } 
    
    if out != nil {
        out.Deptno = in.Deptno 
        if exists, myerr = s.getDept(ctx, tx, out); myerr != nil {
            return false, myerr
        }
        
        if !exists {
            return false, myerror.New("4004", "Row does not exists after updating: reqID, PK", reqID, in.Deptno).PrintfInfo()
        }
    }
    return true, nil
}
Update :
- rollback commit
- , exists = false
func (s *Service) UpdateDept(ctx context.Context, in *model.Dept, out *model.Dept) (exists bool, myerr error) {
    var tx *mysql.Tx
    reqID := myctx.FromContextRequestID(ctx) 
    
    if tx, myerr = s.db.Beginx(reqID); myerr != nil {
        return false, myerr
    }
    
    if exists, myerr = s.updateDept(ctx, tx, in, out); myerr != nil {
        _ = s.db.Rollback(reqID, tx)
        return false, myerr
    }
    
    if !exists {
        _ = s.db.Rollback(reqID, tx)
        return false, nil
    }
    
    if myerr = s.db.Commit(reqID, tx); myerr != nil {
        return false, myerr
    }
    return exists, nil
}
4.3
, .
. , backend , . / , .
3 dgraph-io/ristretto. PostgreSQL listen/notify.
5. JSON
JSON :
- Marshal / Unmarshal JSON
- JSON
JSON . - ( ).
JSON HTTP. , . []byte, JSON.
5.1. Marshal JSON
encode JSON github.com/mailru/easyjson .
, encode JSON Dept:
- HTTP JSON buf []byte
- , w.Buffer.BuildBytes(buf) ,
- HTTP
func deptMarshal(reqID uint64, v *model.Dept, buf []byte) (outBuf []byte, myerr error) {
    w := jwriter.Writer{} 
    v.MarshalEasyJSON(&w) 
    if w.Error != nil {
        return nil, myerror.WithCause("6001", "Error Marshal: reqID", w.Error, reqID).PrintfInfo(1)
    }
    
    return w.Buffer.BuildBytes(buf), nil
    }
5.2. Unmarshal JSON
Decode JSON :
if err := vIn.UnmarshalJSON(inBuf); err != nil {
    return 0, nil, myerror.WithCause("6001", "Error Unmarshal: reqID, buf", err, reqID, string(inBuf)).PrintfInfo()
}
. mailru/easyjson decode , . make new, "" .
:
- out.Emps = make([]*Emp, 0, 8) out.Emps = []*Emp(GetEmpSlice())
- v1 = new(Emp) v1 = GetEmp()
5.3.
5.3.1. Get
Get :
- : id β PK, , buf β JSON
- : outBuf JSON ( buf)
- JSON . vOut := model.GetDept() ( Dept β , Emp β ) defer model.PutDept(vOut, true). .
func (s *Service) GetDept(ctx context.Context, id int, buf []byte) (outBuf []byte, myerr error) {
    vOut := model.GetDept()         
    defer model.PutDept(vOut, true) 
    vOut.Deptno = id                
    
    exists, myerr := s.deptService.GetDept(ctx, vOut)
    if myerr != nil {
        return nil, myerr
    }
    
    if exists {
        return deptMarshal(reqID, vOut, buf)
    }
    return nil, nil 
}
5.3.2. Create
Create :
func (s *Service) CreateDept(ctx context.Context, inBuf []byte, buf []byte) (id int, outBuf []byte, myerr error) {
    vIn := model.GetDept()         
    defer model.PutDept(vIn, true) 
    vOut := model.GetDept()         
    defer model.PutDept(vOut, true) 
    
    if err := vIn.UnmarshalJSON(inBuf); err != nil {
        return 0, nil, myerror.WithCause("6001", "Error Unmarshal: reqID, buf", err, reqID, string(inBuf)).PrintfInfo()
    }
    
    if myerr = s.deptService.CreateDept(ctx, vIn, vOut); myerr != nil {
        return 0, nil, myerr
    }
    
    if outBuf, myerr = deptMarshal(reqID, vOut, buf); myerr != nil {
        return 0, nil, myerr
    }
    return vOut.Deptno, outBuf, myerr
}
5.3.3. Update
Update:
- id β PK .
- outBuf NO_DATA_FOUND
func (s *Service) UpdateDept(ctx context.Context, id int, inBuf []byte, buf []byte) (outBuf []byte, myerr error) {
    vIn := model.GetDept()         
    defer model.PutDept(vIn, true) 
    vOut := model.GetDept()         
    defer model.PutDept(vOut, true) 
    
    if err := vIn.UnmarshalJSON(inBuf); err != nil {
        return nil, myerror.WithCause("6001", "Error Unmarshal: reqID, buf", err, reqID, string(inBuf)).PrintfInfo()
    }
    
    if id != vIn.Deptno {
        return nil, myerror.New("6001", "Resource ID does not corespond to JSON: resource.id, json.Deptno", id, vIn.Deptno).PrintfInfo()
    }
    
    exists, myerr := s.deptService.UpdateDept(ctx, vIn, vOut)
    if myerr != nil {
        return nil, myerr
    }
    
    if exists {
        return deptMarshal(reqID, vOut, buf)
    }
    return nil, nil 
}
5.4. JSON
:
3 JSON go.etcd.io/bbolt. PostgreSQL listen/notify.
6. HTTP
HTTP :
- HTTP
- HTTP
- (basic, MS AD, ...)
- token ( )
- (body)
- (header)
- HSTS Strict-Transport-Security
- Content-Type (response)
- HTTP
- (header)
- defer recovery panic
. HTTP HTTP Golang.
, , :
- defer . UML β RecoverWrap.func1, .
- process. HTTP handler. UML process β .
- HTTP handler. UML EchoHandler.func1 β .
. process, REST API.
( ).

6.1.
JSON, []byte http.ResponseWriter . GC. GC .
- JSON http.ResponseWriter
- JSON http.ResponseWriter
.
, sync.Pool:
:
[HTTP_POOL]
UseBufPool = true           
BufPooledSize = 512         
BufPooledMaxSize = 32768    
process .
var buf []byte
if s.cfg.UseBufPool && s.bytesPool != nil {
    buf = s.bytesPool.GetBuf()
}
, , encode JSON .
, JSON .
[]byte .
if responseBuf != nil && s.cfg.UseBufPool && s.bytesPool != nil {
    
    if cap(responseBuf) >= s.cfg.BufPooledSize && cap(responseBuf) <= s.cfg.BufPooledMaxSize {
        defer s.bytesPool.PutBuf(responseBuf)
    }
}
, . Pointer() []byte.
if reflect.ValueOf(buf).Pointer() != reflect.ValueOf(responseBuf).Pointer() {
    
}
6.2. GET
process, :
- URL ID β PK
- JSON jsonService.GetDept(ctx, id, buf), buf .
- . , header["RequestID"]
func (s *Service) GetDeptHandler(w http.ResponseWriter, r *http.Request) {
    
    _ = s.process("GET", w, r, func(ctx context.Context, requestBuf []byte, buf []byte) ([]byte, Header, int, error) {
        reqID := myctx.FromContextRequestID(ctx) 
        
        vars := mux.Vars(r)
        idStr := vars["id"]
        id, err := strconv.Atoi(idStr)
        if err != nil {
            return nil, nil, http.StatusBadRequest, myerror.WithCause("8001", "Failed to process parameter 'id' invalid number: reqID, id", err, reqID, idStr).PrintfInfo()
        }
        
        responseBuf, err := s.jsonService.GetDept(ctx, id, buf)
        if err != nil {
            return nil, nil, http.StatusInternalServerError, err
        }
        
        if responseBuf == nil {
            return nil, nil, http.StatusNotFound, nil
        }
        
        header := Header{}
        header["Content-Type"] = "application/json; charset=utf-8"
        header["Errcode"] = "0"
        header["RequestID"] = fmt.Sprintf("%v", reqID)
        return responseBuf, header, http.StatusOK, nil
    })
}
6.3. POST
POST :
func (s *Service) CreateDeptHandler(w http.ResponseWriter, r *http.Request) {
    
    _ = s.process("POST", w, r, func(ctx context.Context, requestBuf []byte, buf []byte) ([]byte, Header, int, error) {
        reqID := myctx.FromContextRequestID(ctx) 
        mylog.PrintfDebugMsg("START: reqID", reqID)
        
        id, responseBuf, err := s.jsonService.CreateDept(ctx, requestBuf, buf)
        if err != nil {
            return nil, nil, http.StatusInternalServerError, err
        }
        
        header := Header{}
        header["Content-Type"] = "application/json; charset=utf-8"
        header["Errcode"] = "0"
        header["Id"] = fmt.Sprintf("%v", id)
        header["RequestID"] = fmt.Sprintf("%v", reqID)
        return responseBuf, header, http.StatusOK, nil
    })
    }
6.4. PUT
PUT :
func (s *Service) UpdateDeptHandler(w http.ResponseWriter, r *http.Request) {
    
    _ = s.process("PUT", w, r, func(ctx context.Context, requestBuf []byte, buf []byte) ([]byte, Header, int, error) {
        reqID := myctx.FromContextRequestID(ctx) 
        mylog.PrintfDebugMsg("START: reqID", reqID)
        
        vars := mux.Vars(r)
        idStr := vars["id"]
        id, err := strconv.Atoi(idStr)
        if err != nil {
            return nil, nil, http.StatusBadRequest, myerror.WithCause("8001", "Failed to process parameter 'id' invalid number: reqID, id", err, reqID, idStr).PrintfInfo()
        }
        
        responseBuf, err := s.jsonService.UpdateDept(ctx, id, requestBuf, buf)
        if err != nil {
            return nil, nil, http.StatusInternalServerError, err
        }
        
        if responseBuf == nil {
            return nil, nil, http.StatusNotFound, nil
        }
        
        header := Header{}
        header["Content-Type"] = "application/json; charset=utf-8"
        header["Errcode"] = "0"
        header["RequestID"] = fmt.Sprintf("%v", reqID)
        return responseBuf, header, http.StatusOK, nil
    })
}
6.5.
, httpserver/httpservice Handlers.
type Handler struct {
    Path        string
    HundlerFunc func(http.ResponseWriter, *http.Request)
    Method      string
}
type Handlers map[string]Handler
httpservice.New. , service.recoverWrap().
service.Handlers = map[string]Handler{
    
    "EchoHandler":         Handler{"/echo", service.recoverWrap(service.EchoHandler), "POST"},
    "SinginHandler":       Handler{"/signin", service.recoverWrap(service.SinginHandler), "POST"},
    "JWTRefreshHandler":   Handler{"/refresh", service.recoverWrap(service.JWTRefreshHandler), "POST"},
    "HTTPLogHandler":      Handler{"/httplog", service.recoverWrap(service.HTTPLogHandler), "POST"},
    "HTTPErrorLogHandler": Handler{"/httperrlog", service.recoverWrap(service.HTTPErrorLogHandler), "POST"},
    "LogLevelHandler":     Handler{"/loglevel", service.recoverWrap(service.LogLevelHandler), "POST"},
    
    "CreateDeptHandler": Handler{"/depts", service.recoverWrap(service.CreateDeptHandler), "POST"},
    "GetDeptHandler":    Handler{"/depts/{id:[0-9]+}", service.recoverWrap(service.GetDeptHandler), "GET"},
    "UpdateDeptHandler": Handler{"/depts/{id:[0-9]+}", service.recoverWrap(service.UpdateDeptHandler), "PUT"},
}
7.
7.1.
Oracle 3- :
- VM.DenseIO2.8 β 8 Core Intel (16 virtual core), 120 Memory (GB), Oracle Linux 7.7
- NVMe β 6.4 TB NVMe SSD Storage (1 drives) min 250k IOPS (4k block)
- β 8.2 Network Bandwidth (Gbps)
- β PostgreSQL 12. .
- ApacheBench:
 - concurrency level 4 16384
- 10 000 1 000 000 .
- 2 8 ApacheBench ( ApacheBench 1 )
 

7.2. GET
- JSON β 1800 . Dept 10 Emp.
- Dept β 33 000 000, Emp β 330 000 000 .
:
- GET PostgreSQL
- GET JSON BBolt ( 74 )
- GET ( map)
.
Requests per second Concurrency.

Time per req dependency graph. [ms] from Concurrency (logarithmic scale).

Graph of 99% percentile [ms] versus Concurrency.

Graph of 99% percentile [ms] versus Concurrency (logarithmic scale).

This is how loading the backend server at 100,000 [# / sec] and caching data in BBolt (Concurrency 128) looks like. The average I / O latency on an NVMe drive is 0.02 [ms] (500,000 IOPS).
