Skip to content

Commit

Permalink
Use interface instead of @grpc/grpc-js Client class in public API
Browse files Browse the repository at this point in the history
Since the gRPC Client is a concrete class, changes to private members can cause version-to-version type incompatibilities if the caller has a dependency on a different version of @grpc/grpc-js. Requiring an interface containing only public methods of the gRPC Client class avoids these issues, provided there are no breaking changes in the gRPC Client API.

Signed-off-by: Mark S. Lewis <mark_lewis@uk.ibm.com>
  • Loading branch information
bestbeforetoday committed Feb 10, 2023
1 parent 4483ca6 commit b2d67ac
Show file tree
Hide file tree
Showing 3 changed files with 25 additions and 4 deletions.
2 changes: 1 addition & 1 deletion node/src/gateway.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ describe('Gateway', () => {
it('throws if no identity supplied', () => {
const options = {
client,
} as ConnectOptions;
} as unknown as ConnectOptions;
expect(() => connect(options)).toThrow();
});
});
Expand Down
25 changes: 23 additions & 2 deletions node/src/gateway.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
* SPDX-License-Identifier: Apache-2.0
*/

import { CallOptions, Client } from '@grpc/grpc-js';
import { CallOptions, ChannelInterface, ClientDuplexStream, ClientReadableStream, ClientUnaryCall, ClientWritableStream, Deadline, Metadata, requestCallback } from '@grpc/grpc-js';
import { common, gateway, peer } from '@hyperledger/fabric-protos';
import { ChaincodeEventsRequest, Commit, Proposal, Transaction } from '.';
import { BlockAndPrivateDataEventsRequest, BlockAndPrivateDataEventsRequestImpl, BlockEventsRequest, BlockEventsRequestImpl, FilteredBlockEventsRequest, FilteredBlockEventsRequestImpl } from './blockeventsrequest';
Expand All @@ -19,6 +19,27 @@ import { ProposalImpl } from './proposal';
import { SigningIdentity } from './signingidentity';
import { TransactionImpl } from './transaction';

/**
* Interface describing the public API of the gRPC Client class.
*/
export interface GrpcClient {
close(): void;
getChannel(): ChannelInterface;
waitForReady(deadline: Deadline, callback: (error?: Error) => void): void;
makeUnaryRequest<RequestType, ResponseType>(method: string, serialize: (value: RequestType) => Buffer, deserialize: (value: Buffer) => ResponseType, argument: RequestType, metadata: Metadata, options: CallOptions, callback: requestCallback<ResponseType>): ClientUnaryCall;
makeUnaryRequest<RequestType, ResponseType>(method: string, serialize: (value: RequestType) => Buffer, deserialize: (value: Buffer) => ResponseType, argument: RequestType, metadata: Metadata, callback: requestCallback<ResponseType>): ClientUnaryCall;
makeUnaryRequest<RequestType, ResponseType>(method: string, serialize: (value: RequestType) => Buffer, deserialize: (value: Buffer) => ResponseType, argument: RequestType, options: CallOptions, callback: requestCallback<ResponseType>): ClientUnaryCall;
makeUnaryRequest<RequestType, ResponseType>(method: string, serialize: (value: RequestType) => Buffer, deserialize: (value: Buffer) => ResponseType, argument: RequestType, callback: requestCallback<ResponseType>): ClientUnaryCall;
makeClientStreamRequest<RequestType, ResponseType>(method: string, serialize: (value: RequestType) => Buffer, deserialize: (value: Buffer) => ResponseType, metadata: Metadata, options: CallOptions, callback: requestCallback<ResponseType>): ClientWritableStream<RequestType>;
makeClientStreamRequest<RequestType, ResponseType>(method: string, serialize: (value: RequestType) => Buffer, deserialize: (value: Buffer) => ResponseType, metadata: Metadata, callback: requestCallback<ResponseType>): ClientWritableStream<RequestType>;
makeClientStreamRequest<RequestType, ResponseType>(method: string, serialize: (value: RequestType) => Buffer, deserialize: (value: Buffer) => ResponseType, options: CallOptions, callback: requestCallback<ResponseType>): ClientWritableStream<RequestType>;
makeClientStreamRequest<RequestType, ResponseType>(method: string, serialize: (value: RequestType) => Buffer, deserialize: (value: Buffer) => ResponseType, callback: requestCallback<ResponseType>): ClientWritableStream<RequestType>;
makeServerStreamRequest<RequestType, ResponseType>(method: string, serialize: (value: RequestType) => Buffer, deserialize: (value: Buffer) => ResponseType, argument: RequestType, metadata: Metadata, options?: CallOptions): ClientReadableStream<ResponseType>;
makeServerStreamRequest<RequestType, ResponseType>(method: string, serialize: (value: RequestType) => Buffer, deserialize: (value: Buffer) => ResponseType, argument: RequestType, options?: CallOptions): ClientReadableStream<ResponseType>;
makeBidiStreamRequest<RequestType, ResponseType>(method: string, serialize: (value: RequestType) => Buffer, deserialize: (value: Buffer) => ResponseType, metadata: Metadata, options?: CallOptions): ClientDuplexStream<RequestType, ResponseType>;
makeBidiStreamRequest<RequestType, ResponseType>(method: string, serialize: (value: RequestType) => Buffer, deserialize: (value: Buffer) => ResponseType, options?: CallOptions): ClientDuplexStream<RequestType, ResponseType>;
}

/**
* Options used when connecting to a Fabric Gateway.
* @example
Expand Down Expand Up @@ -47,7 +68,7 @@ export interface ConnectOptions {
* A gRPC client connection to a Fabric Gateway. This should be shared by all gateway instances connecting to the
* same Fabric Gateway. The client connection will not be closed when the gateway is closed.
*/
client: Client;
client: GrpcClient;

/**
* Client identity used by the gateway.
Expand Down
2 changes: 1 addition & 1 deletion node/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ export { CommitStatusError } from './commitstatuserror';
export { Contract } from './contract';
export { EndorseError } from './endorseerror';
export { EventsOptions } from './eventsbuilder';
export { connect, ConnectOptions, Gateway } from './gateway';
export { connect, ConnectOptions, Gateway, GrpcClient } from './gateway';
export { ErrorDetail, GatewayError } from './gatewayerror';
export { Hash } from './hash/hash';
export * as hash from './hash/hashes';
Expand Down

0 comments on commit b2d67ac

Please sign in to comment.