Documentation
¶
Overview ¶
Package controller implements model based generic CRUD controllers (i.e. http handlers) to handle create / read / update / delete requests from http clients. Since crud use Gin web framework as http server, a controller here is actually a gin.HandlerFunc:
GET /models => GetListHandler[Model]: to retrieve a model list
GET /models/:id => GetByIDHandler[Model]: to retrieve a model by id
POST /models => CreateHandler[Model] : to create a new model
PUT /models/:id => UpdateHandler[Model] : to update an existing model
DELETE /models/:id => DeleteHandler[Model] : to delete an existing model
GET /models/:id/field => GetFieldHandler[Model] : to retrieve a field (nested model) of a model
POST /models/:id/field => CreateNestedHandler[Model] : to create a nested model (association)
DELETE /models/:id/field => DeleteNestedHandler[Model] : to delete an association record
The controller are all generic functions, which is available in Go 1.18 and later, see Go generics tutorial for help if you are not familiar with this feature. What you need to notice is that you HAVE TO pass handles the type arguments to specify the model type in the function call, because go have no way to infer them.
Notice that there is not a UpdateNestedHandler, because:
PUT /models/:id/field/:id == PUT /field/:id
Index ¶
- Constants
- Variables
- func CreateHandler[T any]() gin.HandlerFunc
- func CreateNestedHandler[P orm.Model, T orm.Model](parentIDRouteParam string, field string) gin.HandlerFunc
- func DeleteHandler[T orm.Model](idParam string) gin.HandlerFunc
- func DeleteNestedHandler[P orm.Model, T orm.Model](parentIdParam string, field string, childIdParam string) gin.HandlerFunc
- func ErrorResponseBody(err error) gin.H
- func GetByIDHandler[T orm.Model](idParam string) gin.HandlerFunc
- func GetFieldHandler[T orm.Model](idParam string, field string) gin.HandlerFunc
- func GetListHandler[T any]() gin.HandlerFunc
- func ResponseError(c *gin.Context, code int, err error)
- func ResponseSuccess(c *gin.Context, model any, addition ...gin.H)
- func SuccessResponseBody(model any, addition ...gin.H) gin.H
- func UpdateHandler[T orm.Model](idParam string) gin.HandlerFunc
- type GetRequestOptions
Constants ¶
const ( CodeSuccess = http.StatusOK CodeNotFound = http.StatusNotFound CodeBadRequest = http.StatusBadRequest CodeProcessFailed = http.StatusUnprocessableEntity )
Variables ¶
Functions ¶
func CreateHandler ¶
func CreateHandler[T any]() gin.HandlerFunc
CreateHandler handles
POST /T
creates a new model T, responds with the created model T if successful.
Request body:
- {...} // fields of the model T
Response:
- 200 OK: { T: {...} }
- 400 Bad Request: { error: "request band failed" }
- 422 Unprocessable Entity: { error: "create process failed" }
func CreateNestedHandler ¶
func CreateNestedHandler[P orm.Model, T orm.Model](parentIDRouteParam string, field string) gin.HandlerFunc
CreateNestedHandler handles
POST /P/:parentIDRouteParam/T
where:
- P is the parent model, T is the child model
- parentIDRouteParam is the route param name of the parent model P
- field is the field name of the child model T in the parent model P
responds with the updated parent model P
Request body:
- {...} // fields of the child model T
Response:
- 200 OK: { P: {...} }
- 400 Bad Request: { error: "request band failed" }
- 422 Unprocessable Entity: { error: "create process failed" }
func DeleteHandler ¶
func DeleteHandler[T orm.Model](idParam string) gin.HandlerFunc
DeleteHandler handles
DELETE /T/:idParam
Deletes the model T with the given id.
Request body: none
Response:
- 200 OK: { deleted: true }
- 400 Bad Request: { error: "missing id" }
- 422 Unprocessable Entity: { error: "delete process failed" }
func DeleteNestedHandler ¶
func DeleteNestedHandler[P orm.Model, T orm.Model](parentIdParam string, field string, childIdParam string) gin.HandlerFunc
DeleteNestedHandler handles
DELETE /P/:parentIdParam/T/:childIdParam
where:
- P is the parent model, T is the child model
- parentIdParam is the route param name of the parent model P
- childIdParam is the route param name of the child model T in the parent model P
- field is the field name of the child model T in the parent model P
Request body: none
Response:
- 200 OK: { deleted: true }
- 400 Bad Request: { error: "missing id" }
- 422 Unprocessable Entity: { error: "delete process failed" }
func ErrorResponseBody ¶
ErrorResponseBody builds the error response body:
{ error: "error message" }
func GetByIDHandler ¶
func GetByIDHandler[T orm.Model](idParam string) gin.HandlerFunc
GetByIDHandler handles
GET /T/:idParam
QueryOptions (See GetRequestOptions for more details): preload
Response:
- 200 OK: { T: {...} }
- 400 Bad Request: { error: "request band failed" }
- 422 Unprocessable Entity: { error: "get process failed" }
func GetFieldHandler ¶
GetFieldHandler handles
GET /T/:idParam/field
QueryOptions (See GetRequestOptions for more details):
limit, offset, order_by, desc, filter_by, filter_value, preload, total.
Notice, all GetRequestOptions will be conditions for the field, for example:
GET /user/123/order?preload=Product
Preloads User.Order.Product instead of User.Product.
Response:
- 200 OK: { Fs: [{...}, ...] } // field models
- 400 Bad Request: { error: "request band failed" }
- 422 Unprocessable Entity: { error: "get process failed" }
func GetListHandler ¶
func GetListHandler[T any]() gin.HandlerFunc
GetListHandler handles
GET /T
It returns a list of models.
QueryOptions (See GetRequestOptions for more details):
limit, offset, order_by, desc, filter_by, filter_value, preload, total.
Response:
- 200 OK: { Ts: [{...}, ...] }
- 400 Bad Request: { error: "request band failed" }
- 422 Unprocessable Entity: { error: "get process failed" }
func ResponseError ¶
ResponseError writes an error response to client in JSON.
func ResponseSuccess ¶
ResponseSuccess writes a success response to client in JSON.
func SuccessResponseBody ¶
SuccessResponseBody builds the success response body:
{ `model`: { ... } }
where the `model` will be replaced by the model's type name. and addition fields can add any k-v to the response body.
func UpdateHandler ¶
func UpdateHandler[T orm.Model](idParam string) gin.HandlerFunc
UpdateHandler handles
PUT /T/:idParam
Updates the model T with the given id.
Request body:
- {"field": "new_value", ...} // fields to update
Response:
- 200 OK: { updated: true }
- 400 Bad Request: { error: "missing id or bind fields failed" }
- 404 Not Found: { error: "record with id not found" }
- 422 Unprocessable Entity: { error: "update process failed" }
Types ¶
type GetRequestOptions ¶
type GetRequestOptions struct { Limit int `form:"limit"` Offset int `form:"offset"` OrderBy string `form:"order_by"` Descending bool `form:"desc"` FilterBy string `form:"filter_by"` FilterValue string `form:"filter_value"` Preload []string `form:"preload"` // fields to preload Total bool `form:"total"` // return total count ? }
GetRequestOptions is the query options (?opt=val) for GET requests:
limit=10&offset=4& # pagination order_by=id&desc=true& # ordering filter_by=name&filter_value=John& # filtering total=true& # return total count (all available records under the filter, ignoring pagination) preload=Product&preload=Product.Manufacturer # preloading: loads nested models as well
It is used in GetListHandler, GetByIDHandler and GetFieldHandler, to bind the query parameters in the GET request url.