moleculer
moleculer copied to clipboard
[TypeScript] proxy class service methods through broker.createService
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
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)
}
The broker.createService
typing definition returns Service
interface, but it would better return original service with own methods