お疲れ様です。
今日は「service.go、server.goの実装」について部分いたします。
service.goの実装
repositoryでやり取りしたデータをもとにgRPCのレスポンスを返すservice.goの実装をしていきます。
article/service/service.go
package service
import (
"context"
"github.com/k88t76/GraphQL-gRPC-demo/article/pb"
"github.com/k88t76/GraphQL-gRPC-demo/article/repository"
)
type Service interface {
CreateArticle(ctx context.Context, req *pb.CreateArticleRequest) (*pb.CreateArticleResponse, error)
ReadArticle(ctx context.Context, req *pb.ReadArticleRequest) (*pb.ReadArticleResponse, error)
UpdateArticle(ctx context.Context, req *pb.UpdateArticleRequest) (*pb.UpdateArticleResponse, error)
DeleteArticle(ctx context.Context, req *pb.DeleteArticleRequest) (*pb.DeleteArticleResponse, error)
ListArticle(req *pb.ListArticleRequest, stream pb.ArticleService_ListArticleServer) error
}
type service struct {
repository repository.Repository
}
func NewService(r repository.Repository) Service {
return &service{r}
}
func (s *service) CreateArticle(ctx context.Context, req *pb.CreateArticleRequest) (*pb.CreateArticleResponse, error) {
// 記事のCREATE処理
}
func (s *service) ReadArticle(ctx context.Context, req *pb.ReadArticleRequest) (*pb.ReadArticleResponse, error) {
// 記事のREAD処理
}
func (s *service) UpdateArticle(ctx context.Context, req *pb.UpdateArticleRequest) (*pb.UpdateArticleResponse, error) {
// 記事のUPDATE処理
}
func (s *service) DeleteArticle(ctx context.Context, req *pb.DeleteArticleRequest) (*pb.DeleteArticleResponse, error) {
// 記事のDELETE処理
}
func (s *service) ListArticle(req *pb.ListArticleRequest, stream pb.ArticleService_ListArticleServer) error {
// 記事の全取得処理
}
CREATE
article/service/service.go
func (s *service) CreateArticle(ctx context.Context, req *pb.CreateArticleRequest) (*pb.CreateArticleResponse, error) {
// INSERTする記事のInput(Author, Title, Content)を取得
input := req.GetArticleInput()
// 記事をDBにINSERTし、INSERTした記事のIDを返す
id, err := s.repository.InsertArticle(ctx, input)
if err != nil {
return nil, err
}
// INSERTした記事をレスポンスとして返す
return &pb.CreateArticleResponse{
Article: &pb.Article{
Id: id,
Author: input.Author,
Title: input.Title,
Content: input.Content,
},
}, nil
}
READ
article/service/service.go
func (s *service) ReadArticle(ctx context.Context, req *pb.ReadArticleRequest) (*pb.ReadArticleResponse, error) {
// READする記事のIDを取得
id := req.GetId()
// DBから該当IDの記事を取得
a, err := s.repository.SelectArticleByID(ctx, id)
if err != nil {
return nil, err
}
// 取得した記事をレスポンスとして返す
return &pb.ReadArticleResponse{
Article: &pb.Article{
Id: id,
Author: a.Author,
Title: a.Title,
Content: a.Content,
},
}, nil
}
UPDATE
func (s *service) UpdateArticle(ctx context.Context, req *pb.UpdateArticleRequest) (*pb.UpdateArticleResponse, error) {
// UPDATEする記事のIDを取得
id := req.GetId()
// UPDATEする記事の変更内容(Author, Title, Content)を取得
input := req.GetArticleInput()
// 該当IDの記事をUPDATE
if err := s.repository.UpdateArticle(ctx, id, input); err != nil {
return nil, err
}
// UPDATEした記事をレスポンスとして返す
return &pb.UpdateArticleResponse{
Article: &pb.Article{
Id: id,
Author: input.Author,
Title: input.Title,
Content: input.Content,
},
}, nil
}
DELETE
article/service/service.go
func (s *service) DeleteArticle(ctx context.Context, req *pb.DeleteArticleRequest) (*pb.DeleteArticleResponse, error) {
// DELETEする記事のIDを取得
id := req.GetId()
// 該当IDの記事をDELETE
if err := s.repository.DeleteArticle(ctx, id); err != nil {
return nil, err
}
// DELETEした記事のIDをレスポンスとして返す
return &pb.DeleteArticleResponse{Id: id}, nil
}
全取得
article/service/service.go
func (s *service) ListArticle(req *pb.ListArticleRequest, stream pb.ArticleService_ListArticleServer) error {
// 記事を全取得
rows, err := s.repository.SelectAllArticles()
if err != nil {
return err
}
defer rows.Close()
// 取得した記事を1つ1つレスポンスとしてServer Streamingで返す
for rows.Next() {
var a pb.Article
err := rows.Scan(&a.Id, &a.Author, &a.Title, &a.Content)
if err != nil {
return err
}
stream.Send(&pb.ListArticleResponse{Article: &a})
}
return nil
}
これでarticleサービスの実装は完了です!
server.goの実装
gRPCサーバーを起動するserver.goの実装をしていきます。
今回gRPCサーバーはgRPCのデフォルトポートである50051に立てることにします。
article/server/server.go
package main
import (
"log"
"net"
"github.com/k88t76/GraphQL-gRPC-demo/article/pb"
"github.com/k88t76/GraphQL-gRPC-demo/article/repository"
"github.com/k88t76/GraphQL-gRPC-demo/article/service"
"google.golang.org/grpc"
)
func main() {
// articleサーバーに接続
lis, err := net.Listen("tcp", ":50051")
if err != nil {
log.Fatalf("Failed to listen: %v\n", err)
}
defer lis.Close()
// Repositoryを作成
repository, err := repository.NewsqliteRepo()
if err != nil {
log.Fatalf("Failed to create sqlite repository: %v\n", err)
}
// Serviceを作成
service := service.NewService(repository)
//サーバーにarticleサービスを登録
server := grpc.NewServer()
pb.RegisterArticleServiceServer(server, service)
//articleサーバーを起動
log.Println("Listening on port 50051...")
if err := server.Serve(lis); err != nil {
log.Fatalf("Failed to serve: %v", err)
}
}
上記のようにしてarticleサービスを実装したgRPCサーバーを立てることができます。
試しに起動してみましょう。
go run article/server/server.go
起動するとDBが作成され、articleディレクトリにarticle.sqlが現れたはずです。
次はclient.goの実装をしていきましょう!
今日は以上です。
ありがとうございました。
よろしくお願いいたします。