0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Go言語で学ぶWebアプリケーション開発3:[Docker + gRPCを組み込む]

Posted at

はじめに

前回の記事では、バックエンドにGo + Ginを使用、フロントエンドにはReact + Viteを使用して作成したWebアプリケーションにデータベース連携(GORM + SQLite)とJWT認証機能を追加しました。
今回は、さらにDockerを使ってアプリケーションをコンテナ化し、gRPCを組み込むことで、より高度なWebアプリケーションへと発展させます。
自分でもこのあたりは初めてやった時には複雑だったので、知識の整理も兼ねて解説します。

対象読者

  • GoでWebアプリを作成し、Dockerを活用して環境構築を行いたい方
  • REST APIだけでなく、gRPCを導入してさらにパフォーマンスの向上を図りたい方
  • Webアプリケーションをより実用的な形でデプロイしたい方

目次

  1. Dockerを使った環境構築
    • そもそものDockerの基本概念
    • Dockerfileの作成
    • Docker Composeを使ったサービス管理
  2. gRPCの組み込み
    • gRPCの基本概念
    • Protocol Buffers(.proto)の定義
    • gRPCサーバーの実装
    • gRPCクライアントの実装
  3. フロントエンドとの統合
    • ReactからREST API & gRPCを呼び出す方法
    • フロントエンドでのgRPCの利用方法

1. Docker を使った環境構築

1.1 Docker の基本概念

Dockerは、アプリケーションを コンテナ という単位で管理・実行するツールです。
コンテナを使うことで、環境の差異をなくし、どこでも同じように動作するアプリケーションを作ることができます。

1.2 Dockerfileの作成

まず、アプリケーションをDockerで動かせるようにするための Dockerfile を作成します。

Dockerfile

# ベースイメージ
FROM golang:1.19

# 作業ディレクトリを作成
WORKDIR /app

# 必要なファイルをコピー
COPY go.mod .
COPY go.sum .
RUN go mod download

# ソースコードをコピー
COPY . .

# アプリケーションをビルド
RUN go build -o main .

# ポート 8080 を開放
EXPOSE 8080

# アプリケーションを実行
CMD ["./main"]

1.3 Docker Composeを使ったサービス管理

docker-compose.ymlを作成し、バックエンド、データベース、フロントエンドをまとめて管理できるようにします。

docker-compose.yml

version: '3.8'
services:
  backend:
    build: .
    ports:
      - "8080:8080"
    depends_on:
      - database
  database:
    image: sqlite
  frontend:
    build: ./frontend
    ports:
      - "5173:5173"
    depends_on:
      - backend

docker-compose upを実行すれば、すべてのサービスがコンテナとして起動します。

docker-compose up --build

2. gRPCの組み込み

2.1 gRPC の基本概念

gRPCは、Googleが開発した高性能なRPC(Remote Procedure Call)フレームワーク です。

  • 軽量 & 高速:バイナリ形式のProtocol Buffers(protobuf)を使用するため、REST APIよりも効率的。
  • 双方向ストリーミング:クライアントとサーバーの双方向通信が可能。
  • マイクロサービスに最適:マルチ言語対応で、拡張性が高い。

2.2 Protocol Buffers (.proto) の定義

まず、gRPCの通信を定義する.protoファイルを作成します。

proto/todo.proto

syntax = "proto3";
package todo;

service TodoService {
    rpc GetTodos (Empty) returns (TodoList);
}

message Empty {}

message Todo {
    int32 id = 1;
    string task = 2;
    bool status = 3;
}

message TodoList {
    repeated Todo todos = 1;
}

2.3 gRPC サーバーの実装

server.go

package main

import (
    "context"
    "net"
    "log"

    "google.golang.org/grpc"
    pb "todo/proto"
)

type server struct {
    pb.UnimplementedTodoServiceServer
}

func (s *server) GetTodos(ctx context.Context, req *pb.Empty) (*pb.TodoList, error) {
    todos := []*pb.Todo{
        {Id: 1, Task: "Learn Go", Status: false},
        {Id: 2, Task: "Build a Web App", Status: true},
    }
    return &pb.TodoList{Todos: todos}, nil
}

func main() {
    lis, err := net.Listen("tcp", ":50051")
    if err != nil {
        log.Fatalf("failed to listen: %v", err)
    }
    s := grpc.NewServer()
    pb.RegisterTodoServiceServer(s, &server{})
    log.Println("gRPC server is running on port 50051")
    if err := s.Serve(lis); err != nil {
        log.Fatalf("failed to serve: %v", err)
    }
}

3. フロントエンドとの統合

3.1 ReactからREST API & gRPCを呼び出す方法

  • REST API: Axiosを使用
axios.get("http://localhost:8080/api/todos")
    .then(response => console.log(response.data));
  • gRPC: gRPC-Webを使用
import { TodoServiceClient } from "./proto/TodoServiceClientPb";
const client = new TodoServiceClient("http://localhost:50051");
client.getTodos({}, (err, response) => console.log(response));

まとめ

項目 説明
Docker アプリをコンテナ化し、どこでも同じ環境で動作させる
gRPC 高速なバイナリ通信が可能なRPCフレームワーク
REST API & gRPC の統合 フロントエンドで両方の通信方式を活用

本記事では、Dockerを使ってアプリをコンテナ化し、gRPCを導入する方法を解説しました。
少し難しめの概念ですが、とても効率的なアプリケーション開発が可能になるため、この辺りもマスターしていきましょう!

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?