@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

Dependencies (17)

Dev Dependencies (16)

Package Sidebar

Install

npm i @lakutata-module/service

Weekly Downloads

32

Version

1.2.7

License

MIT

Unpacked Size

469 kB

Total Files

196

Last publish

Collaborators

  • myq1991