Add a controller
Before we adding any logic to our application, first we need a controller and its route. Remember the hello
controller? You have used it in the previous chapter.
- hello.go
- hello.go
- hello_new.go
- hello_v1_hello.go
- hello.go
The route is registered in internal/cmd/cmd.go
:
s.Group("/", func(group *ghttp.RouterGroup) {
group.Middleware(ghttp.MiddlewareHandlerResponse)
group.Bind(
hello.NewV1(),
)
})
This method using here is called Standardized Routing
in GoFrame
, which is easy to use and could be combined with code generation command gf gen ctrl
. The API documentation would also be generated automatically, see Swagger page hello.
We recommend to use Standardized Routing
since it would be better to maintain and extend. You could also find other ways of routing here.
Create API structure
To use the code generation command gf gen ctrl
, you need to declare the API structure first. GoFrame
require certain file structure to generate controller, which is api/{model}/{version}/{definition}.go
. And the API structure name is also require to end with Req
and Res
. Let’s create a new API in RESTful
way for our message:
package v1
import "github.com/gogf/gf/v2/frame/g"
type CreateMessageReq struct {
g.Meta `path:"/" tags:"Message" method:"post" sum:"Create a message"`
UserUid string `json:"user_uid" v:"required|size:10" des:"Message sender ID" eg:"0000000000"`
Content string `json:"content" v:"required|length:1,100" des:"Message content" eg:"This is my first message."`
}
type CreateMessageRes struct {
g.Meta `mime:"application/json"`
Code int `json:"code" v:"required" des:"Status code" eg:"0"`
Message string `json:"message" v:"required" des:"Status message" eg:"Success"`
Data interface{} `json:"data"`
}
The g.Meta
here is used to add additional attributes to Request
or Response
. For this request, path
is used to define the route, tags
is used to set group in OpenAPI
documentation, method
is used to declare the accept HTTP method and sum
is used to add summary to the route. And for the response, mime
is just used to set the response content type.
Tags in structure could not only be used to generate OpenAPI
documentation, but also to validate data or transform data. For example, v
tag could be used to validate data in request. For our request here, the UserUID
is set to be required and the length should be 10, similar for other fields. Documentation for validation here.
Those tags seems a little confusing, but don’t worry, you will see their function clearly soon after we register the route. Or you could also find more details for gtag
here.
Generate Controller
Now we could use gf gen ctrl
to generate controller with those structures declared before:
& gf gen ctrl
generated: ...\api\hello\hello.go
generated: ...\api\message\message.go
generated: internal\controller\message\message.go
generated: internal\controller\message\message_new.go
generated: internal\controller\message\message_v1_create_message.go
done!
And you will see its structure is similar to the hello
controller auto-generated before.
api
directory, you could use some auto-run plugin, like Run on Save
in VSCode.Open the internal\controller\message\message_v1_create_message.go
, you will see the implementation of controller here:
func (c *ControllerV1) CreateMessage(ctx context.Context, req *v1.CreateMessageReq) (res *v1.CreateMessageRes, err error) {
return nil, gerror.NewCode(gcode.CodeNotImplemented)
}
The response is not implemented yet, we may add some code later.
Register route
After generate controller, we need to register the route. Open the cmd.go
in internal\cmd
folder, the hello
we used before has been registered here:
s.Group("/", func(group *ghttp.RouterGroup) {
group.Middleware(ghttp.MiddlewareHandlerResponse)
group.Bind(
hello.NewV1(),
)
})
We could add the message
similarly:
s.Group("/messages", func(group *ghttp.RouterGroup) {
group.Middleware(ghttp.MiddlewareHandlerResponse)
group.Bind(
message.NewV1(),
)
})
Since the path
we set before is /
, we need to add messages
to the route group when registering. You could also set the path in api
structure to /messages
, and you can ignore the messages
here.
route used for controller if api path
is set to /messages
s.Group("/", func(group *ghttp.RouterGroup) {
group.Middleware(ghttp.MiddlewareHandlerResponse)
group.Bind(
hello.NewV1(),
message.NewV1(),
)
})
Test your result
Good job! You have successfully created your first API and registered the route. Check it in Swagger here.
If you have used tools like Postman
, you could test the API with the following request:
POST http://localhost:8000/messages
{
"user_uid": "0000000000",
"content": "This is my first message."
}
Or use curl
to test the API:
curl -X POST -H "Content-Type: application/json" -d '{"user_uid":"0000000000","content":"This is my first message."}' "http://localhost:8000/messages"
You will see the Not Implemented
response like this:
{
"code": 58,
"message": "Not Implemented",
"data": null
}