grpc-node icon indicating copy to clipboard operation
grpc-node copied to clipboard

loadObject() throwing the same error as load()

Open ksztengel opened this issue 1 year ago • 1 comments

Problem description

.load() has been deprecated and it is stated in both the error and the documentation: Use the proto-loader module with grpc.loadPackageDefinition instead.

.loadObject is to Load a ProtoBuf.js object as a gRPC object. When it's called this error is thrown

export const loadObject = (value: any, options: any): never => {
  throw new Error(
    'Not available in this library. Use @grpc/proto-loader and loadPackageDefinition instead'
  );
};

Is this intentional?

Reproduction steps

Add pbjs reflection Service to a grpc server with

const { pbjsService } = service;
      const grpcObj = grpc.loadObject(pbjsService, {
        enumsAsStrings: false,
      });


pbjs.Service
/** Reflected service. */
export class Service extends NamespaceBase {

    /**
     * Constructs a new service instance.
     * @param name Service name
     * @param [options] Service options
     * @throws {TypeError} If arguments are invalid
     */
    constructor(name: string, options?: { [k: string]: any });

    /** Service methods. */
    public methods: { [k: string]: Method };

    /**
     * Constructs a service from a service descriptor.
     * @param name Service name
     * @param json Service descriptor
     * @returns Created service
     * @throws {TypeError} If arguments are invalid
     */
    public static fromJSON(name: string, json: IService): Service;

    /**
     * Converts this service to a service descriptor.
     * @param [toJSONOptions] JSON conversion options
     * @returns Service descriptor
     */
    public toJSON(toJSONOptions?: IToJSONOptions): IService;

    /** Methods of this service as an array for iteration. */
    public readonly methodsArray: Method[];

    /**
     * Creates a runtime service using the specified rpc implementation.
     * @param rpcImpl RPC implementation
     * @param [requestDelimited=false] Whether requests are length-delimited
     * @param [responseDelimited=false] Whether responses are length-delimited
     * @returns RPC service. Useful where requests and/or responses are streamed.
     */
    public create(rpcImpl: RPCImpl, requestDelimited?: boolean, responseDelimited?: boolean): rpc.Service;
}

Environment

  • OS name, version and architecture: Mac Sonoma version 14.3, Apple M3 Pro
  • Node version 16.14.2
  • Node installation method nvm
  • Package name and version [email protected]

Additional context

I can understand deprecating load but not loadObject - there isn't a work around to add protobuf.js object as grpc that I could find.

ksztengel avatar Mar 08 '24 21:03 ksztengel

Yes, this is intentional. We decided early on that the public API of @grpc/grpc-js should not interact with the API of Protobuf.js in this way. As the error message says, the supported alternative is to load the proto file using @grpc/proto-loader (which uses Protobuf.js internally) and then pass the output in to loadPackageDefinition.

Alternatively, the PackageDefinition interface is pretty generic, so you could transform the pbjsService object you have into a PackageDefinition and then pass that in to loadPackageDefinition. The @grpc/proto-loader source code should get you most of the way there. If you just have a single service there, you could also generate a single ServiceDefinition object and pass that to the makeClientConstructor function.

murgatroid99 avatar Mar 08 '24 22:03 murgatroid99