Next, we'll implement the microservices calls within our controllers to handle specific business logic.
In real-world development, complex business logic should be encapsulated in the
logic
layer, similar to monolithic web services, and then called by controllers.
User Service
app/gateway/internal/controller/user/user_v1_login.go
package user
import (
"context"
account "proxima/app/user/api/account/v1"
"proxima/app/gateway/api/user/v1"
)
func (c *ControllerV1) Login(ctx context.Context, req *v1.LoginReq) (res *v1.LoginRes, err error) {
user, err := c.AccountClient.UserLogin(ctx, &account.UserLoginReq{
Username: req.Username,
Password: req.Password,
})
if err != nil {
return nil, err
}
return &v1.LoginRes{
Token: user.GetToken(),
}, nil
}
Let's test the gateway-to-microservice communication with a request:
$ curl -X POST http://127.0.0.1:8000/v1/users/login \
-H "Content-Type: application/json" \
-d '{
"username": "oldme",
"password": "12345678"
}'
{
"code": 0,
"message": "",
"data": {
"token": "I am token"
}
}
Congratulations on seeing this response! You can now try implementing the other services as well. Here's the source code for reference.
Word Service
app/gateway/internal/controller/words/words_v1_create.go
package words
import (
"context"
words "proxima/app/word/api/words/v1"
"proxima/app/gateway/api/words/v1"
)
func (c *ControllerV1) Create(ctx context.Context, req *v1.CreateReq) (res *v1.CreateRes, err error) {
_, err = c.WordsClient.Create(ctx, &words.CreateReq{
Uid: 1,
Word: req.Word,
Definition: req.Definition,
})
if err != nil {
return nil, err
}
return &v1.CreateRes{}, nil
}
app/gateway/internal/controller/words/words_v1_detail.go
package words
import (
"context"
"github.com/gogf/gf/v2/errors/gerror"
words "proxima/app/word/api/words/v1"
"proxima/app/gateway/api/words/v1"
)
func (c *ControllerV1) Detail(ctx context.Context, req *v1.DetailReq) (res *v1.DetailRes, err error) {
word, err := c.WordsClient.Get(ctx, &words.GetReq{
Id: uint32(req.Id),
})
if err != nil {
return nil, err
}
if word == nil {
return nil, gerror.New("word not found")
}
return &v1.DetailRes{
Id: uint(word.Words.Id),
Word: word.Words.Word,
Definition: word.Words.Definition,
}, nil
}