After preparing the data model, we can use our "three-step" rule to develop the user interface.
Add API
api/users/v1/users.go
package v1
import "github.com/gogf/gf/v2/frame/g"
type RegisterReq struct {
g.Meta `path:"users/register" method:"post"`
Username string `json:"username"`
Password string `json:"password"`
Email string `json:"email"`
}
type RegisterRes struct {
}
For better maintenance of the interface, a version number is usually added at the beginning of the interface address. GoFrame
recommends using multi-level directories to manage versions, and the version number of this interface is v1
.
RegisterReq
and RegisterRes
define the HTTP request object and response object respectively. g.Meta
is embedded into the request structure and defines general interface attributes through the Go Tag
method. This code means we have added a user registration interface, with the address /users/register
, request method POST
, and three request parameters: Username
, Password
, and Email
.
Execute the command to generate the Controller
corresponding to the API:
$ gf gen ctrl
generated: D:\project\star\api\users\users.go
generated: internal\controller\users\users.go
generated: internal\controller\users\users_new.go
generated: internal\controller\users\users_v1_register.go
done!
Among the four generated files, we only need to focus on users_v1_register.go
, which is used to receive HTTP requests and call Logic
to complete the business process.
If you have installed the GoFrame Helper plugin, the
gf gen ctrl
command will be executed automatically. You can also use the official automatic generation method: Tutorial Configuration.
Write Logic
Logic
is the business logic layer, stored in internal/logic
, which is called by the Controller
to implement specific business logic.
internal/logic/users/register.go
package users
import (
"context"
"star/internal/dao"
"star/internal/model/do"
)
func Register(ctx context.Context, username, password, email string) error {
_, err := dao.Users.Ctx(ctx).Data(do.Users{
Username: username,
Password: password,
Email: email,
}).Insert()
if err != nil {
return err
}
return nil
}
dao.Users
is the data access object generated earlier, used for interacting with the database. do.Users
is the generated data model used for data entry, and there is a similar data model entity.Users
used for data output.
Controller Calls Logic
The Controller
layer is responsible for receiving Req
request objects and then calling one or more Logic
to complete the business logic. Some simple logic can also be directly handled in the Controller
. The results of the processing are wrapped in the agreed Res
data structure and returned. Here, the Res
data structure is empty, so returning nil
is sufficient.
internal/controller/users/users_v1_register.go
package users
import (
"context"
"star/internal/logic/users"
"star/api/users/v1"
)
func (c *ControllerV1) Register(ctx context.Context, req *v1.RegisterReq) (res *v1.RegisterRes, err error) {
err = users.Register(ctx, req.Username, req.Password, req.Email)
return nil, err
}
Register the Controller
All controllers must be registered in cmd
to be effective. The cmd
layer is responsible for guiding the program to start, with significant work including initializing logic, registering route objects, starting the server
to listen, and blocking the running program until the server
exits.
internal/cmd/cmd.go
package cmd
···
var (
Main = gcmd.Command{
Name: "main",
Usage: "main",
Brief: "start http server",
Func: func(ctx context.Context, parser *gcmd.Parser) (err error) {
s := g.Server()
s.Group("/", func(group *ghttp.RouterGroup) {
group.Middleware(ghttp.MiddlewareHandlerResponse)
group.Group("/v1", func(group *ghttp.RouterGroup) {
group.Bind(
users.NewV1(),
)
})
})
s.Run()
return nil
},
}
)
group.Group
is a method for grouped route registration provided by the framework, and it is the recommended registration method by the framework. We prefix with v1
corresponding to the api
directory to facilitate interface version management.
Run the Project
$ gf run main.go
build: .\main.go
go build -o .\main.exe .\main.go
.\main.exe
build running pid: 8648
2024-11-08 10:36:48.013 [INFO] pid[8648]: http server started listening on [:8000]
2024-11-08 10:36:48.013 [INFO] {e05c16b565dd0518360ebe639e1c623d} swagger ui is serving at address: http://127.0.0.1:8000/swagger/
2024-11-08 10:36:48.014 [INFO] {e05c16b565dd0518360ebe639e1c623d} openapi specification is serving at address: http://127.0.0.1:8000/api.json
ADDRESS | METHOD | ROUTE | HANDLER | MIDDLEWARE
----------|--------|--------------------|---------------------------------------------------------|----------------------------------
:8000 | ALL | /api.json | github.com/gogf/gf/v2/net/ghttp.(*Server).openapiSpec |
----------|--------|--------------------|---------------------------------------------------------|----------------------------------
:8000 | ALL | /swagger/* | github.com/gogf/gf/v2/net/ghttp.(*Server).swaggerUI | HOOK_BEFORE_SERVE
----------|--------|--------------------|---------------------------------------------------------|----------------------------------
:8000 | POST | /v1/users/register | star/internal/controller/users.(*ControllerV1).Register | ghttp.MiddlewareHandlerResponse
----------|--------|--------------------|---------------------------------------------------------|----------------------------------
The result of running prints out three interface addresses. /swagger
and /api.json
are interface document addresses generated by the framework, which we will explain in detail in 2.5 API Documentation. The other address /v1/users/register
is the user registration interface we developed. Send a POST
request to test it.
$ curl -X POST http://127.0.0.1:8000/v1/users/register -H "Content-Type: application/json" -d "{\"username\":\"oldme\", \"password\":\"123456\", \"email\":\"tyyn1022@gmail.com\"}"
{
"code":0,
"message":"",
"data":null
}
A code
of 0
indicates success. Check the database to see if a record has been inserted:
SELECT * FROM users;
ID | Username | Password | Created_At | Updated_At | |
---|---|---|---|---|---|
1 | oldme | 123456 | tyyn1022@gmail.com | 2024-11-08 10:36:48 | 2024-11-08 10:36:48 |
Created_At
and Updated_At
are two convention fields that will be automatically maintained by the ORM
, representing the creation time and modification time respectively.