Basics
It is unbelievably simple to transform Nest application into Nest microservice. Take a look - this is how you create web application:
将Nest应用程序转换为Nest微服务非常简单。 让我们来看看如何创建web应用程序。
const app = NestFactory.create(ApplicationModule);
app.listen(3000, () => console.log('Application is listening on port 3000'));
Now, switch it to a microservice:
现在,将应用程序转换为微服务:
const app = NestFactory.createMicroservice(ApplicationModule, { port: 3000 });
app.listen(() => console.log('Microservice is listening on port 3000'));
It's everything!
就是如此!
TCP通信
By default Nest microservice is listening for messages via TCP protocol. It means that right now e.g. @Get() will not be useful, because it is mapping HTTP requests. So, how microservice will recognize messages? Just by patterns. What is pattern? It is nothing special. It could be an object, string or even number (but it is not a good idea). Let's create MathController:
默认情况下, Nest微服务是通过TCP协议
监听消息的。也就是说现在@Get()将用武之地,因为它映射HTTP
请求。所以微服务是怎么识别消息的呢?--通过模式识别。
模式是什么呢?模式不是什么特殊的东西,它可以是对象、字符串或者数字(这不是一个好想法)。
我们来创建一个MathController
:
import { MessagePattern } from '@nestjs/microservices';
@Controller()
export class MathController {
@MessagePattern({ cmd: 'add' })
public add(data: number[]): Observable<number> {
const numbers = data || [];
return Observable.of(numbers.reduce((a, b) => a + b));
}
}
As you might seen - if you want to create message handler, you have to decorate it wih @MessagePattern(pattern). In this example, I chose { cmd: 'add' } as a pattern. The handler method receives single argument - data, which is a variable with data sent from another microservice (or just web application). Also, the handler returns Observable from Rxjs package, so it's possible to return multiple values. IMPORTANT! You have to complete Observable if you want to terminate the data stream.
如上所示,如果你想创建一个消息handler
,你必须用@MessagePattern(模式)
来装饰这个handler
。在上面的例子中,我是用的是{ cmd: 'add' }
模式。
handler
接受由另一个微服务(或者web应用程序)发送的单个参数--数据变量。
同时,handler
从Rxjs package
返回监控属性,所以可能会返回多个值。注意!如果想种植数据流必须完成监控属性。
客户端
You already know how to listen for messages. Now, let's check how to send them from another microservice or web application. Before you can start, Nest has to know, where you're exactly going to send messages. It's easy - you only have to create @Client object.
你已经了解了如何监听消息。现在我们来看看如何从另一个微服务或者web应用程序发送消息。
在开始之前,你必须告诉Nest你要将消息发送到哪里。很简单,你只需要创建一个@Client
对象即可。
import { Controller } from '@nestjs/common';
import { Client, ClientProxy, Transport } from '@nestjs/microservices';
@Controller()
export class ClientController {
@Client({ transport: Transport.TCP, port: 5667 })
client: ClientProxy;
}
@Client() decorator receives object as a parameter. This object can have 3 properties:
- transport - with this you can decide which method you're going to use - TCP or Redis (TCP by default),
- url - only for Redis purposes (default - redis://localhost:6379),
- port (default 3000).
@Client装饰器接收对象作为参数。该对象有以下三个属性:
transport
- 这个属性帮助你决定通信方式---TCP
还是Redis
(默认使用TCP
).url
- 仅用于Redis(默认--redis://localhost:6379
)。port
(默认为3000
)。
使用客户端
Let's create custom endpoint to test our communication.
让我们来创建端点来测试通信。
import { Controller, Get } from '@nestjs/common';
import { Client, ClientProxy, Transport } from '@nestjs/microservices';
@Controller()
export class ClientController {
@Client({ transport: Transport.TCP, port: 5667 })
client: ClientProxy;
@Get('client')
public sendMessage(@Res() res: Response) {
const pattern = { cmd: 'add' };
const data = [ 1, 2, 3, 4, 5 ];
this.client.send(pattern, data)
.catch((err) => Observable.empty())
.subscribe((result) => res.status(200).json({ result }));
}
}
As you might seen, in order to send message you have to use send method, which receives message pattern and data as an arguments. This method returns an Observable. It is very important feature, because reactive Observables provide set of amazing operators to deal with, e.g. combine, zip, retryWhen, timeout and more... Of course, if you want to use Promises instead of Observables, you could simply use toPromise() method. That's all.
如上所示,要发送消息就必须使用send
方法,该方法接收消息模式和数据作为参数,并返回一个监控属性。
这是一个非常重要的功能,因为反应监控属性提供了一组强大的操作来处理,例如combine
, zip
, retryWhen
, timeout
等等。
当然,如果你想使用Promises
代替Observables
,只需使用toPromise()
属性即可。
Now, when someone will make /test request (GET), that's how response should looks like (if both microservice and web app are available):
现在,当有人发送 /test request
(GET)时,response
将会显示如下(如果微服务和 web 应用都可用):
{
"result": 15
}