@lakutata-module/service
TypeScript icon, indicating that this package has built-in type declarations

1.2.7 • Public • Published

NPM Version NODE Version Known Vulnerabilities NPM Download

Features

  • Micro-service
  • Distributed Events
  • Cross nodes service invoking (directly|chain|parallel)
  • Scalable

Quickstart

Service Examples

Service Registry Example

const serviceRegistryApp = await createApp({
    id: 'registry.service.test.app',
    name: 'test-service-registry',
    modules: {
        registry: {
            class: ServiceRegistry,
            logger: true,
            redisOptions: {
                host: '192.168.0.132'
            },
            token: '123456'
        }
    }
})
serviceRegistryApp.Logger.info(serviceRegistryApp.getID(), 'is running')

Service Provider Example

 const serviceProviderApp = await createApp({
    id: 'provider.service.test.app',
    name: 'test-service-provider',
    modules: {
        provider: {
            class: Service,
            registry: '127.0.0.1',
            token: '123456',
            controllers: [
                `${path.resolve(__dirname, '../controllers')}/**/*`
            ],
            logger: true
        }
    }
})
serviceProviderApp.Logger.info(serviceProviderApp.getID(), 'is running')

Service Consumer Example

const serviceConsumerApp = await createApp({
    id: 'consumer.service.test.app',
    name: 'test-service-consumer',
    modules: {
        consumer: {
            class: Service,
            registry: '127.0.0.1',
            token: '123456',
            services: [
                `${path.resolve(__dirname, '../services')}/**/*`
            ],
            logger: true
        }
    }
})
serviceConsumerApp.Logger.info(serviceConsumerApp.getID(), 'is running')
setTimeout(async () => {
    serviceConsumerApp.Logger.info('Service consumer test begin:')
    const consumer = serviceConsumerApp.Modules.get<Service>('consumer')
    consumer.channel('test').on('test', (x, y, z) => {
        serviceConsumerApp.Logger.debug('Received channel event [test] data:', x, y, z)
    })
    consumer.channel('test').triggerOne('test', 'a', 'b', 'c')
    try {
        serviceConsumerApp.Logger.info('Start test manually service invoking:')
        serviceConsumerApp.Logger.debug('Service chain invoke result:', await consumer.invoke({
                serviceId: 'provider.service.test.app',
                data: {test: true},
                transform: (response) => {
                    return {name: response}
                }
            },
            {
                serviceId: 'provider.service.test.app',
                data: {
                    test: true,
                    ccc: true
                },
                transform: (response) => {
                    return `this is response:${response}`
                }
            }))
        serviceConsumerApp.Logger.debug('Service parallel invoke result:', await consumer.parallel({
                serviceId: 'provider.service.test.app',
                data: {test: true},
                transform: (response) => {
                    return `this is response:${response}`
                }
            }, [
                {
                    serviceId: 'provider.service.test.app',
                    data: {test: true},
                    transform: (response) => {
                        return {test: true}
                    }
                },
                {
                    serviceId: 'provider.service.test.app',
                    data: {
                        test: true,
                        name: 'manually service invoking',
                        ccc: true
                    },
                    transform: (response) => {
                        return `this is response:${response}`
                    }
                }
            ]
        ))
    } catch (e) {
        serviceConsumerApp.Logger.error(e)
    }
}, 3000)

Service Controller Examples (For Service Provider)

TestController1

@Controller()
export class TestController1 extends BaseController {
    @Accept(Validator.Object({
        name: Validator.String.required()
    }))
    @PATTERN({test: true, ccc: true})
    public async serviceTest(a: any) {
        return a.name
    }

    @PATTERN({test: true, abd: true})
    public async serviceTest2() {
        return [true, true]
    }
}

TestController2

@Controller()
export class TestController2 extends BaseController {
    @PATTERN({test: true})
    public async tc2Test() {
        return 'this is tc2 test'
    }
}

@lakutata/core required.

Documentations

Configure Service Module (Registry|Provider|Consumer)

Service Registry Options

Name DataType Default Required Description
port Number 6911 No Service registry listen port
token String No Service registry access toke for clients
logger Boolean/Logger false No Log service registry activities
redisOptions RedisOptions No If not set, the service registry is running in single node mode, else it will build a cluster automatically

Service Options

Name DataType Default Required Description
registry String Yes Service registry address url,if port not specified, it will be 6911
controllers String\String[] No The service controllers load path/paths
timeout Number 60000(ms) No Service consumer invoke remote service timeout
retry Number 0 No If service consumer invoke remote service return a retryable error, it will retry to invoke again until the retry chances decreases to 0
token String No Service registry access token
logger Boolean\Logger false No Log service consumer activities

Service Controller

A valid service controller MUST extend BaseController, and it MUST decorate by @Controller(), the @Controller() decorator has an optional parameter:

@Controller(basicPattern: TPattern = {})

if basicPattern set, all patterns declared in the controller will contain it.

In the service controller, @PATTERN() decorator is for decorate method, the parameter is the invoking pattern.

@PATTERN(pattern: TPattern)

Classes

  • ServiceRegistry (Module)

    • fetchServices(appId?: string | RegExp): { [appId: string]: IServiceInfo[] }
  • Service (Module)

    • async invoke(...params: TInvokeObject[]): Promise
    • async parallel(...params: (TInvokeObject | TInvokeObject[])[]): Promise<any[]>
    • channel(name: string): Channel
      • trigger(event: string, ...args: any[]): boolean
      • triggerAll(event: string, ...args: any[]): boolean
      • triggerOne(event: string, ...args: any[]): boolean
      • directTrigger(serviceId: string, event: string, ...args: any[]): boolean
      • directTriggerAll(serviceId: string, event: string, ...args: any[]): boolean
      • directTriggerOne(serviceId: string, event: string, ...args: any[]): boolean
      • privateTrigger(event: string, ...args: any[]): boolean
      • privateTriggerAll(event: string, ...args: any[]): boolean
      • privateTriggerOne(event: string, ...args: any[]): boolean
      • on(event: string, listener: (...args: any[]) => void): Channel
      • once(event: string, listener: (...args: any[]) => void): Channel
      • off(event?: string, listener?: (...args: any[]) => void): Channel
    • channels(): string[]
    • async fetchServices(appId?: string | RegExp): Promise<{ [appId: string]: IServiceInfo[] }>
  • BaseController

Decorators

  • @Controller
  • @PATTERN

Exceptions

  • BrokenServiceInvokeException
  • IncorrectTokenException
  • InvalidRegistryProtocolException
  • PatternNotFoundException
  • RequestException
  • RequestTimeoutException
  • ServiceClientInitializationException
  • ServiceInvokeTimeoutException
  • ServiceProviderNotFoundException
  • ServiceRegistryInitializationException

Examples

Examples can be found in project src/tests.

How to Contribute

Please let us know how can we help. Do check out issues for bug reports or suggestions first.

License

MIT

Package Sidebar

Install

npm i @lakutata-module/service

Weekly Downloads

11

Version

1.2.7

License

MIT

Unpacked Size

469 kB

Total Files

196

Last publish

Collaborators

  • myq1991