moleculer icon indicating copy to clipboard operation
moleculer copied to clipboard

[TypeScript] proxy class service methods through broker.createService

Open cloudever opened this issue 5 years ago • 2 comments

Hi there! I started using Moleculer a couple of days ago and I very pleased with the development process.

I've found a solution to create client service for remote existing service and use one as a provider in GraphQL gateway (apollo server) for example:

const SERVICE_NAME = 'my_service'

class MyService extends Service {
  constructor(broker) {
    super(broker);

    this.parseServiceSchema({
      name: SERVICE_NAME,
      actions: {
        [Action.GetProviderList]: this.getProviderList,
      }
    })
  }

  async getProviderList() {
    // code
  }
}


class MyServiceClient extends Service {
  constructor(broker) {
    super(broker);

    this.parseServiceSchema({
      name: SERVICE_NAME + ':client',
      actions: {
        [Action.GetProviderList]: this.getProviderList,
      }
   })
  }

  async getProviderList() {
    return this.broker.call(SERVICE_NAME + '.' + Action.GetProviderList)
  }
}

And there's a way to use client service as a provider

const myServiceClient = broker.createService(MyServiceClient)
const data = await myServiceClient.getProviderList();

It's a working solution but typescript does not know about getProviderList method in client MyServiceClient, and currently, I use the following approach:

const myServiceClient = new MyServiceClient(broker)

Is it possible to add typings for proxying class methods?

cloudever avatar Aug 12 '19 20:08 cloudever

@cloudever

I am not sure I fully understood the question: if what you mean is that getProviderList is not visible in TS so you need to define it as public + using decorators is quite helpful. I use services defined in the following manner without any trouble

@Service({})
class DocusignResourceAccess extends moleculer.Service {

    @Action({
        params: {
            filledPdf: {type: 'string'}
        },
        visibility: 'public'
    })
    public async submitToSign(ctx: AuthContext<{ filledPdf: string, user: UserDefinition }>) {
        try {
            const {filledPdf, user} = ctx.params;
            
        } catch (e) {
            this.logger.error(e.message, e);
            throw e;
        }
    }

    @Method
    private _recipientViewRequest(user: UserDefinition) {

        
    }

    @Method
    private _constructEnvelope(filledPdf: string, user: UserDefinition) {
      
    }
}

module.exports = DocusignResourceAccess;

on the other hand if what you refer to is that you do not have the typesc defined from the call - so simply add method signature for example:

async getProviderList(): Promise<ResultInterfaceSignature> {
    return this.broker.call(SERVICE_NAME + '.' + Action.GetProviderList)
  }

dkuida avatar Aug 25 '19 23:08 dkuida

The broker.createService typing definition returns Service interface, but it would better return original service with own methods

cloudever avatar Nov 06 '19 02:11 cloudever