[gRPC] Simple gRPC calls with Golang and Flutter
grpc, flutter, golang, protobuf ·
Post Series (click to expand)
Implementing gRPC server with Protobuf, Golang, Flutter
π Part 2 - [gRPC] Simple gRPC calls with Golang and Flutter
gRPC Server
μ΄μ ν¬μ€νΈμμ μ»΄νμΌλ μ½λλ₯Ό μ΄μ©νμ¬ Golang μΌλ‘ gRPC μλ²λ₯Ό λ§λ€μ΄λ³΄μ.
Go Modules
νλ‘μ νΈ λ£¨νΈμ go.mod νμΌμ μλ λ΄μ©μ μΆκ°νλ€.
require (
...
protocols v1.0.0
)
...
replace (
protocols => ../protocols
)
μμ§μ Github λ±μ git repository μ μ¬λ¦¬μ§ μκ³ , λ‘컬μμ μν¬νΈν κ²μ΄κΈ° λλ¬Έμ replace
ꡬ문μ μ΄μ©νμ¬ μλκ²½λ‘λ₯Ό μ§μ ν΄μ€λ€. λ‘컬 μλ κ²½λ‘λ‘ replace ν κ²½μ° λ²μ μ€νΈλ§μ vX.Y.Z μ ν¬λ§·λ§ μ§μΌμ μμλ‘ λ£μ΄μ£Όλ©΄ λλ€.
μ 체 Project μ root λλ ν 리μ server, client, protocols μ λλ ν 리λ₯Ό λ§λ€κ³ κ·Έ μμ κ°κ°μ νλ‘μ νΈλ₯Ό μμ±νλ©΄ μλ κ²½λ‘λ‘ μ°Έμ‘°νκΈ°κ° νΈνλ€.
example βββ client βββ protocols βββ server
API server
RPC API μ λ‘μ§μ μ€ννλ λΆλΆ. λ°μ΄ν°λ₯Ό μ μ₯νκ³ , μ°Ύμμ€κ³ , μμ νλ λ± API νΈμΆμ λ°λ₯Έ business logic μ΄ λ€μ΄κ° λΆλΆμ΄λ€. λ¨Όμ μμμ protobuf λ₯Ό μ΄μ©ν΄ μμ±ν μ½λλ₯Ό μ΄ν΄λ³΄λ©΄,
...
// UserApiServer is the server API for UserApi service.
// All implementations must embed UnimplementedUserApiServer
// for forward compatibility
type UserApiServer interface {
GetUser(context.Context, *GetUserRequest) (*GetUserReply, error)
AddUser(context.Context, *AddUserRequest) (*AddUserReply, error)
mustEmbedUnimplementedUserApiServer()
}
// UnimplementedUserApiServer must be embedded to have forward compatible implementations.
type UnimplementedUserApiServer struct {
}
func (UnimplementedUserApiServer) GetUser(context.Context, *GetUserRequest) (*GetUserReply, error) {
return nil, status.Errorf(codes.Unimplemented, "method GetUser not implemented")
}
func (UnimplementedUserApiServer) AddUser(context.Context, *AddUserRequest) (*AddUserReply, error) {
return nil, status.Errorf(codes.Unimplemented, "method AddUser not implemented")
}
func (UnimplementedUserApiServer) mustEmbedUnimplementedUserApiServer() {}
...
βservice UserApi
β λ‘ μ€μ ν rpc νΈμΆμ λ°μ μ μλ interface κ° μ μλμ΄ μλ€. μ£Όμμ μ€λͺ
λλ‘ UnimplementedUserApiServer
interface λ₯Ό μλ² λνμ¬ API server ꡬ쑰체λ₯Ό μ μνκ³ , νμν API handler function λ€μ ꡬννλ€.
import(
...
"google.golang.org/grpc/codes"
"google.golang.org/grpc/status"
"protocols/goapi"
)
// API server struct.
type UserApi struct {
goapi.UnimplementedUserApiServer
}
func (u *UserApi) GetUser(ctx context.Context, request *goapi.GetUserRequest) (*goapi.GetUserReply, error) {
// rpc GetUser(GetUserRequest) returns (GetUserReply) {}
...
// example success return
return &goapi.GetUserReply{
Users: []*goapi.User{user},
}, nil
// example error return
return nil, status.Errorf(codes.NotFound, "email: %s", email)
}
func (u *UserApi) AddUser(ctx context.Context, request *goapi.AddUserRequest) (*goapi.AddUserReply, error) {
// rpc AddUser(AddUserRequest) returns (AddUserReply) {}
}
grpc Server
API server λ₯Ό μ μνκ³ κ΅¬νν λ€, κ°μ²΄λ₯Ό μμ±νμ¬ grpc server κ°μ²΄μ λ±λ‘ν΄μ£Όλ©΄ ν΄λΉνλ rpc call μ΄ λΌμ°ν λμ΄ handler function μ΄ μ€νλλ€.
import (
...
"google.golang.org/grpc"
"protocols/goapi"
)
func main() {
// grpc server κ°μ²΄λ₯Ό μμ±
grpcServer := grpc.NewServer()
// UserApi κ°μ²΄λ₯Ό μμ±νμ¬ grpc server μ λ±λ‘
goapi.RegisterUserApiServer(grpcServer, &UserApi{})
lis, err := net.Listen("tcp", ":8080")
if err != nil {
log.Fatal(err)
}
if err := grpcServer.Serve(lis); err != nil {
log.Fatal(err)
}
}
gRPC Client
Flutter μμ grpc client λ₯Ό λ§λ€κ³ , rpc call μ ν΅ν΄ λ°μ΄ν°λ₯Ό λ°μ μΆλ ₯ν΄λ³΄μ.
Import protocols
Protocol Buffer compiler κ° μμ±ν νμΌμ μν¬νΈνλ€. pubspec.yaml
μ dependencies μΉμ
μ μλ λ΄μ©μ μΆκ°.
grpc: ^3.0.2
dartapi:
path: ../protocols/dartapi
gRPC Client
Future<List<User>> getUser() async {
final channel = ClientChannel('localhost',
port: 8080,
options: ChannelOptions(
credentials: const ChannelCredentials.insecure(),
)
);
UserApiClient userApiClient = UserApiClient(channel);
final resp = await userApiClient.getUser(
GetUserRequest()..email="user@email.com"
);
return resp.users;
}
μλ² μͺ½μ λΉνλ©΄ μλΉν λ¨μνλ€. λ‘컬 ν
μ€νΈ λ¨κ³μμ μνΈνλ₯Ό μ¬μ©νμ§ μμ κ²μ΄λ―λ‘, ChannelCredentials.insecure()
μ΅μ
μ μ§μ νκ³ grpc.ClientChannel
μ μμ±νλ€. μ΄ μ±λμ μ΄μ©νλ UserApiClient
λ₯Ό μμ±νκ³ , ν΄λΌμ΄μΈνΈ κ°μ²΄μ member function μ νΈμΆνλ©΄ rpc κ° νΈμΆλλ€.