Перейти к содержанию

Java

Официальный SDK

Основные классы для работы

  • ManagedChannel — абстракция канала до сервера. Используйте один и тот же канал во всём приложении.

    При создании канала рекомендуем использовать метод io.grpc.ManagedChannelBuilder#useTransportSecurity, так как сервер API поддерживает только защищённое соединение.

    Для автоматической проверки работоспособности канала при иницииализации используйте метод io.grpc.ManagedChannelBuilder#keepAliveTime. Допустимое время keepAlive — не меньше 10 секунд.

  • Stub — сгенерированные классы клиентов для сервисов API. Есть три варианта клиентов:

    • Не блокирующий — ServiceNameStub, например InstrumentsServiceStub. Все методы такого клиента принимают два параметра: запрос и обработчик результата вызова io.grpc.stub.StreamObserver. Методы обработчика будут вызваны после получения результата. Не рекомендуется выполнять блокирующие операции (I/O, любые операции с ожиданием завершения) в методах обработчика.
    • Блокирующий — ServiceNameBlockingStub, например InstrumentsServiceBlockingStub. Все методы такого клиента принимают один параметр — запрос — и возвращают результат либо выбрасывают исключение. Вызов метода блокирует поток исполнения до получения результата или исключения.
    • Асинхронный — ServiceNameFutureStub, например InstrumentsServiceFutureStub. Все методы такого клиента принимают один параметр — запрос — и возвращают объект типа com.google.common.util.concurrent.ListenableFuture.

Таймаут запроса

В gRPC вместо таймаута используется deadline — время в будущем, до наступления которого будет ожидаться выполнение вызова.

Если результат не получен и deadline наступил, возникнет ошибка с кодом DEADLINE_EXCEEDED. При этом может быть ситуация, когда на сервере API операция была обработана успешно. Для критичных действий используйте ключ идемпотентности.

Рекомендуем устанавливать deadline через метод io.grpc.stub.AbstractStub#withDeadlineAfter.

Обратите внимание
Период времени начинает отсчитываться сразу после отправки запроса через метод.

Метаданные

Метаданные — аналог заголовков в HTTP.

Передача метаданных запроса

Чтобы использовать API, нужно передавать метаданные с ключом Authorization и значением bearer {token}. Подробнее.

Перехватчик можно добавить в канал через метод io.grpc.ManagedChannelBuilder#intercept(io.grpc.ClientInterceptor...). Пример авторизационного перехватичка:

public class AuthInterceptor implements ClientInterceptor {

    private static final String AUTH_HEADER_NAME = "Authorization";
    private static final Metadata.Key<String> AUTH_HEADER = Metadata.Key.of(AUTH_HEADER_NAME, Metadata.ASCII_STRING_MARSHALLER);

    private final String authHeaderValue;

    public AuthInterceptor(String token) {
        this.authHeaderValue = "Bearer " + token;
    }

    @Override
    public <ReqT, RespT> ClientCall<ReqT, RespT> interceptCall(MethodDescriptor<ReqT, RespT> methodDescriptor, CallOptions callOptions, Channel channel) {
        var call = channel.newCall(methodDescriptor, callOptions);
        return new ForwardingClientCall.SimpleForwardingClientCall<>(call) {
            @Override
            public void start(Listener<RespT> responseListener, Metadata headers) {
                headers.put(AUTH_HEADER, authHeaderValue);
                super.start(responseListener, headers);
            }
        };
    }
}

Получение метаданных ответа

В метаданных ответа для Unary-методов передаются идентификатор отслеживания и описание ошибки.

Для получения метаданных ответа можно использовать перехватчик io.grpc.stub.MetadataUtils#newCaptureMetadataInterceptor, например:

var headersCapture = new AtomicReference<Metadata>();
var trailersCapture = new AtomicReference<Metadata>();
instruments.withInterceptors(MetadataUtils.newCaptureMetadataInterceptor(headersCapture, trailersCapture)).getInstrumentBy(...);

После исполнения метода метаданные ответа вернутся в переменной headersCapture.

При работе с методами клиентов конвертируйте исключения в статус через io.grpc.Status#fromThrowable. В поле description статуса вернётся код ошибки.