快速开始

使用 Node.js 开发后端微服务

基于 Dubbo 定义的 Triple 协议,你可以轻松编写浏览器、gRPC 兼容的 RPC 服务,并让这些服务同时运行在 HTTP/1 和 HTTP/2 上。Dubbo Node.js SDK 支持使用 IDL 或编程语言特有的方式定义服务,并提供一套轻量的 API 来发布或调用这些服务。

本示例演示了基于 Triple 协议的 RPC 通信模式,示例使用 Protocol Buffer 定义 RPC 服务,并演示了代码生成、服务发布和服务访问等过程。

前置条件

因为使用 Protocol Buffer 的原因,我们首先需要安装相关的代码生成工具,这包括 @bufbuild/protoc-gen-es@bufbuild/protobuf@apachedubbo/protoc-gen-apache-dubbo-es@apachedubbo/dubbo

  1. npm install @bufbuild/protoc-gen-es @bufbuild/protobuf @apachedubbo/protoc-gen-apache-dubbo-es @apachedubbo/dubbo

定义服务

现在,使用 Protocol Buffer (IDL) 来定义一个 Dubbo 服务。

创建目录,并生成文件

  1. mkdir -p proto && touch proto/example.proto

写入内容

  1. syntax = "proto3";
  2. package apache.dubbo.demo.example.v1;
  3. message SayRequest {
  4. string sentence = 1;
  5. }
  6. message SayResponse {
  7. string sentence = 1;
  8. }
  9. service ExampleService {
  10. rpc Say(SayRequest) returns (SayResponse) {}
  11. }

这个文件声明了一个叫做 ExampleService 的服务,为这个服务定义了 Say 方法以及它的请求参数 SayRequest 和返回值 SayResponse

生成代码

创建 gen 目录,做为生成文件放置的目标目录

  1. mkdir -p gen

运行以下命令,在 gen 目录下生成代码文件

  1. PATH=$PATH:$(pwd)/node_modules/.bin \
  2. protoc -I proto \
  3. --es_out gen \
  4. --es_opt target=ts \
  5. --apache-dubbo-es_out gen \
  6. --apache-dubbo-es_opt target=ts \
  7. example.proto

运行命令后,应该可以在目标目录中看到以下生成的文件:

  1. ├── gen
  2. ├── example_dubbo.ts
  3. └── example_pb.ts
  4. ├── proto
  5. └── example.proto

实现服务

接下来我们就需要添加业务逻辑了,实现 ExampleService ,并将其注册到 DubboRouter 中。

创建 dubbo.ts 文件

  1. import { DubboRouter } from "@apachedubbo/dubbo";
  2. import { ExampleService } from "./gen/example_dubbo";
  3. export default (router: DubboRouter) =>
  4. // registers apache.dubbo.demo.example.v1
  5. router.service(ExampleService, {
  6. // implements rpc Say
  7. async say(req) {
  8. return {
  9. sentence: `You said: ${req.sentence}`,
  10. };
  11. },
  12. }, { serviceGroup: 'dubbo', serviceVersion: '1.0.0' });

启动 Server

Dubbo 服务可以嵌入到普通的 Node.js 服务器、Next.js、Express 或 Fastify 中。 在这里我们将使用 Fastify,所以让我们安装 Fastify 以及我们为 Fastify 准备的插件。

  1. npm install fastify @apachedubbo/dubbo-fastify

创建 server.ts 文件,新建一个 Server,把上一步中实现的 ExampleService 注册给它。 接下来就可以直接初始化和启动 Server 了,它将在指定的端口接收请求。

  1. import { fastify } from "fastify";
  2. import { fastifyDubboPlugin } from "@apachedubbo/dubbo-fastify";
  3. import routes from "./dubbo";
  4. async function main() {
  5. const server = fastify();
  6. await server.register(fastifyDubboPlugin, {
  7. routes,
  8. });
  9. server.get("/", (_, reply) => {
  10. reply.type("text/plain");
  11. reply.send("Hello World!");
  12. });
  13. await server.listen({ host: "localhost", port: 8080 });
  14. console.log("server is listening at", server.addresses());
  15. }
  16. void main();

最后,运行代码启动服务

  1. npx tsx server.ts

访问服务

最简单方式是使用 HTTP/1.1 POST 请求访问服务,参数则作以标准 JSON 格式作为 HTTP 负载传递。如下是使用 cURL 命令的访问示例:

  1. curl \
  2. --header 'Content-Type: application/json' \
  3. --header 'TRI-Service-Version: 1.0.0' \
  4. --header 'TRI-Service-group: dubbo' \
  5. --data '{"sentence": "Hello World"}' \
  6. http://localhost:8080/apache.dubbo.demo.example.v1.ExampleService/Say

也可以使用标准的 Dubbo client 请求服务,我们首先需要从生成代码即 dubbo-node 包中获取服务代理,为它指定 server 地址并初始化,之后就可以发起起 RPC 调用了。

创建 client.ts 文件。

  1. import { createPromiseClient } from "@apachedubbo/dubbo";
  2. import { ExampleService } from "./gen/example_dubbo";
  3. import { createDubboTransport } from "@apachedubbo/dubbo-node";
  4. const transport = createDubboTransport({
  5. baseUrl: "http://localhost:8080",
  6. httpVersion: "1.1",
  7. });
  8. async function main() {
  9. const client = createPromiseClient(ExampleService, transport, { serviceVersion: '1.0.0', serviceGroup: 'dubbo' });
  10. const res = await client.say({ sentence: "Hello World" });
  11. console.log(res);
  12. }
  13. void main();

运行客户端

  1. npx tsx client.ts

最后修改 September 13, 2024: Refactor website structure (#2860) (1a4b998f54b)