To build a gRPC service with Gradle, Java, and Avro

To build a gRPC service with Gradle, Java, and Avro, follow these steps. This example will walk you through creating a basic user data service that allows clients to send and retrieve user information.


Project Structure

grpc-avro-user-service/
│
├── src/
│   ├── main/
│   │   ├── avro/
│   │   │   └── user.avsc
│   │   ├── java/
│   │   │   ├── proto/
│   │   │   │   └── UserService.proto
│   │   │   └── com/example/userservice/
│   │   │       ├── UserServiceImpl.java
│   │   │       └── App.java
├── build.gradle
└── settings.gradle

Step-by-Step Guide

1. Define the Avro Schema (user.avsc)

Create an Avro schema for user data, which will be serialized and used by the service.

src/main/avro/user.avsc:

{
  "namespace": "com.example.userservice",
  "type": "record",
  "name": "User",
  "fields": [
    { "name": "id", "type": "string" },
    { "name": "name", "type": "string" },
    { "name": "email", "type": "string" },
    { "name": "age", "type": "int" }
  ]
}

2. Define the gRPC Service (UserService.proto)

Define a gRPC service in the proto folder.

src/main/java/proto/UserService.proto:

syntax = "proto3";

package com.example.userservice;

message UserRequest {
  string id = 1;
}

message UserResponse {
  string id = 1;
  string name = 2;
  string email = 3;
  int32 age = 4;
}

service UserService {
  rpc GetUser(UserRequest) returns (UserResponse);
}

3. Configure build.gradle

Configure the build.gradle file to include necessary plugins for gRPC, Avro, and Java.

plugins {
    id 'java'
    id 'com.google.protobuf' version '0.9.1'
    id 'com.github.davidmc24.gradle.plugin.avro' version '1.3.0'
}

group = 'com.example'
version = '1.0-SNAPSHOT'
sourceCompatibility = '11'

repositories {
    mavenCentral()
}

dependencies {
    implementation 'io.grpc:grpc-netty-shaded:1.56.0'
    implementation 'io.grpc:grpc-protobuf:1.56.0'
    implementation 'io.grpc:grpc-stub:1.56.0'
    implementation 'org.apache.avro:avro:1.11.0'
    compileOnly 'org.apache.avro:avro-compiler:1.11.0'
    testImplementation 'junit:junit:4.13.2'
}

protobuf {
    protoc {
        artifact = "com.google.protobuf:protoc:3.22.0"
    }
    plugins {
        grpc {
            artifact = 'io.grpc:protoc-gen-grpc-java:1.56.0'
        }
    }
    generateProtoTasks {
        all()*.plugins {
            grpc {}
        }
    }
}

avro {
    source = file("src/main/avro")
    outputCharacterEncoding = 'UTF-8'
}

test {
    useJUnitPlatform()
}

4. Implement the Service (UserServiceImpl.java)

Create the gRPC service implementation that reads user data.

src/main/java/com/example/userservice/UserServiceImpl.java:

package com.example.userservice;

import com.example.userservice.proto.UserRequest;
import com.example.userservice.proto.UserResponse;
import com.example.userservice.proto.UserServiceGrpc;
import io.grpc.stub.StreamObserver;

public class UserServiceImpl extends UserServiceGrpc.UserServiceImplBase {

    @Override
    public void getUser(UserRequest request, StreamObserver<UserResponse> responseObserver) {
        // Dummy data: Normally, you would fetch this from a database or other source
        UserResponse response = UserResponse.newBuilder()
                .setId(request.getId())
                .setName("John Doe")
                .setEmail("john.doe@example.com")
                .setAge(30)
                .build();

        responseObserver.onNext(response);
        responseObserver.onCompleted();
    }
}

5. Create the Main Application (App.java)

Write a class to start the gRPC server.

src/main/java/com/example/userservice/App.java:

package com.example.userservice;

import io.grpc.Server;
import io.grpc.ServerBuilder;

import java.io.IOException;

public class App {
    public static void main(String[] args) throws IOException, InterruptedException {
        Server server = ServerBuilder.forPort(8080)
                .addService(new UserServiceImpl())
                .build();

        System.out.println("Starting gRPC server on port 8080...");
        server.start();
        server.awaitTermination();
    }
}

6. Generate Code from Proto and Avro

  1. Compile the Protobuf files by running:

    ./gradlew generateProto
    
  2. Compile the Avro schema:

    ./gradlew generateAvro
    

7. Run the Application

To run the gRPC server:

./gradlew run

8. Test the gRPC Service

You can use grpcurl to test the service.

First, install grpcurl:

  • On MacOS: brew install grpcurl

Then, invoke the GetUser method:

grpcurl -plaintext -d '{ "id": "123" }' localhost:8080 com.example.userservice.UserService/GetUser

Expected Response:

{
  "id": "123",
  "name": "John Doe",
  "email": "john.doe@example.com",
  "age": 30
}

9. Summary

In this example, you have set up a gRPC service in Java using Gradle and Avro. The gRPC service provides a simple API to fetch user data based on a user ID. Avro is used to manage data serialization, though in this minimal example we used a static response. This setup can be extended to fetch data from a database and use Avro-encoded messages for efficient data transfer.

Let me know if you need further help!

댓글

이 블로그의 인기 게시물

Install and run an FTP server using Docker

Using the MinIO API via curl

PYTHONPATH, Python 모듈 환경설정

Elasticsearch Ingest API

오늘의 문장2

How to checkout branch of remote git, 깃 리모트 브랜치 체크아웃

Fundamentals of English Grammar #1

To switch to a specific tag in a Git repository

You can use Sublime Text from the command line by utilizing the subl command

티베트-버마어파 와 한어파(중국어파)의 어순 비교