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!

댓글

이 블로그의 인기 게시물

Using the MinIO API via curl

How to split a list into chunks of 100 items in JavaScript, 자바스크립트 리스트 쪼개기

HTML Inline divisions at one row by Tailwind

Boilerplate for typescript server programing

가속도 & 속도

Gradle multi-module project

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

CDPEvents in puppeteer

Sparse encoder

Reactjs datetime range picker