Lakutata Service Module
npm install @lakutata-module/service




- Micro-service
- Distributed Events
- Cross nodes service invoking (directly|chain|parallel)
- Scalable
#### Service Registry Example
``typescript`
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
`typescript${path.resolve(__dirname, '../controllers')}/*/
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: [
`
],
logger: true
}
}
})
serviceProviderApp.Logger.info(serviceProviderApp.getID(), 'is running')
#### Service Consumer Example
`typescript${path.resolve(__dirname, '../services')}/*/
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: [
this is response:${response}
],
logger: true
}
}
})
serviceConsumerApp.Logger.info(serviceConsumerApp.getID(), 'is running')
setTimeout(async () => {
serviceConsumerApp.Logger.info('Service consumer test begin:')
const consumer = serviceConsumerApp.Modules.get
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 `
}
}
]
))
} catch (e) {
serviceConsumerApp.Logger.error(e)
}
}, 3000)
#### TestController1
`typescript
@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
`typescript``
@Controller()
export class TestController2 extends BaseController {
@PATTERN({test: true})
public async tc2Test() {
return 'this is tc2 test'
}
}
> @lakutata/core required.
#### 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 |
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)
- ServiceRegistry (Module)
- fetchServices(appId?: string | RegExp): { [appId: string]: IServiceInfo[] }
- Service (Module)
- async invoke(...params: TInvokeObject[]): Promise
- async parallel(...params: (TInvokeObject | TInvokeObject[])[]): Promise
- 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
- @Controller
- @PATTERN
- BrokenServiceInvokeException
- IncorrectTokenException
- InvalidRegistryProtocolException
- PatternNotFoundException
- RequestException
- RequestTimeoutException
- ServiceClientInitializationException
- ServiceInvokeTimeoutException
- ServiceProviderNotFoundException
- ServiceRegistryInitializationException
Examples can be found in project src/tests.
Please let us know how can we help. Do check out issues for bug reports
or suggestions first.