
# Java {/* #java */}

Empieza por la [guía de gRPC](/docs/es/api/grpc) para obtener un token API de la plataforma y descargar `platform.proto`. El contrato del cliente define `java_package = "dev.reconstruct.platform.v1"` y genera clases Java independientes para sus mensajes. Este ejemplo utiliza Gradle y el [plugin protobuf de gRPC para Java](https://github.com/grpc/grpc-java#generated-code).

Coloca `platform.proto` en `src/main/proto/platform.proto`. Añade este `build.gradle`:

```groovy
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 genera las clases de mensajes y `PlatformServiceGrpc` al compilar el proyecto. Guarda esto como `src/main/java/dev/reconstruct/example/Main.java`:

```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();
        }
    }
}
```

Ejecuta `gradle run` (o `./gradlew run` si tu proyecto tiene un wrapper de Gradle). El gRPC nativo utiliza la autoridad TLS, no la ruta REST `/api/v1`.
