Java
Start with the gRPC guide to get a Platform API token and download platform.proto. The client contract sets java_package = "dev.reconstruct.platform.v1" and generates separate Java classes for its messages. This example uses Gradle and the gRPC Java protobuf plugin.
Place platform.proto at src/main/proto/platform.proto. Add this build.gradle:
plugins {
id 'java'
id 'application'
id 'com.google.protobuf' version '0.9.5'
}
repositories { mavenCentral() }
def grpcVersion = '1.84.0'
dependencies {
implementation "io.grpc:grpc-protobuf:${grpcVersion}"
implementation "io.grpc:grpc-stub:${grpcVersion}"
runtimeOnly "io.grpc:grpc-netty-shaded:${grpcVersion}"
compileOnly 'javax.annotation:javax.annotation-api:1.3.2'
}
protobuf {
protoc { artifact = 'com.google.protobuf:protoc:3.25.8' }
plugins {
grpc { artifact = "io.grpc:protoc-gen-grpc-java:${grpcVersion}" }
}
generateProtoTasks {
all()*.plugins { grpc {} }
}
}
application { mainClass = 'dev.reconstruct.example.Main' }
Gradle generates the message classes and PlatformServiceGrpc when it builds the project. Save this as src/main/java/dev/reconstruct/example/Main.java:
package dev.reconstruct.example;
import dev.reconstruct.platform.v1.GetCatalogRequest;
import dev.reconstruct.platform.v1.ListCatalogsRequest;
import dev.reconstruct.platform.v1.PlatformServiceGrpc;
import io.grpc.Grpc;
import io.grpc.ManagedChannel;
import io.grpc.Metadata;
import io.grpc.TlsChannelCredentials;
import io.grpc.stub.MetadataUtils;
import java.util.concurrent.TimeUnit;
public final class Main {
public static void main(String[] args) throws Exception {
String token = System.getenv("CR_RECONSTRUCT_API_TOKEN");
if (token == null || token.isBlank()) {
throw new IllegalStateException("Set CR_RECONSTRUCT_API_TOKEN");
}
ManagedChannel channel = Grpc.newChannelBuilderForAddress(
"reconstruct.dev", 443, TlsChannelCredentials.create()).build();
try {
Metadata headers = new Metadata();
headers.put(Metadata.Key.of("authorization", Metadata.ASCII_STRING_MARSHALLER),
"Bearer " + token);
var client = PlatformServiceGrpc.newBlockingStub(channel)
.withInterceptors(MetadataUtils.newAttachHeadersInterceptor(headers))
.withDeadlineAfter(10, TimeUnit.SECONDS);
var page = client.listCatalogs(ListCatalogsRequest.newBuilder().setPageSize(10).build());
for (var catalog : page.getCatalogsList()) {
var detail = client.getCatalog(GetCatalogRequest.newBuilder()
.setCatalogId(catalog.getCatalogId()).build());
System.out.println(detail.getCatalogId() + ": " + detail.getDescription());
}
} finally {
channel.shutdownNow();
}
}
}
Run gradle run (or ./gradlew run if your project has a Gradle wrapper). Native gRPC uses the TLS authority, not the /api/v1 REST path.