浏览器可直接访问 Dubbo、gRPC 后端微服务,Dubbo-js 首个alpha 版本来了!

本文涉及的产品
云原生网关 MSE Higress,422元/月
注册配置 MSE Nacos/ZooKeeper,118元/月
Serverless 应用引擎免费试用套餐包,4320000 CU,有效期3个月
简介: 浏览器可直接访问 Dubbo、gRPC 后端微服务,Dubbo-js 首个alpha 版本来了!

作者:蔡建怿


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


Dubbo-js 已于 9 月份发布支持 Dubbo3 协议的首个 alpha 版本,它的发布将有机会彻底改变微服务前后端的架构与通信模式,让你能直接在浏览器页面或 web 服务器中访问后端 Dubbo、gRPC 服务。目前项目快速发展中,对参与 apache/dubbo-js 项目感兴趣的开发者,欢迎搜索钉钉群:29775027779 加入开发者群组。



浏览器 Web 应用示例


本示例演示了如何使用 dubbo-js 开发运行在浏览器上的 web 应用程序,web 页面将调用 dubbo node.js 开发的后端服务并生成页面内容。本示例演示基于 IDL 和非 IDL 两种编码模式。



IDL 模式

前置条件

首先,我们将使用 Vite 来生成我们的前端项目模板,它内置了我们稍后需要的所有功能支持。


npm create vite@latest -- dubbo-web-example --template react-ts
cd dubbo-web-example
npm install


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


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


使用 Proto 定义服务

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


src 下创建 util/proto 目录,并生成文件。


mkdir -p src/util/proto && touch src/util/proto/example.proto


写入内容:


syntax = "proto3";
package apache.dubbo.demo.example.v1;
message SayRequest {
  string sentence = 1;
}
message SayResponse {
  string sentence = 1;
}
service ExampleService {
  rpc Say(SayRequest) returns (SayResponse) {}
}


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


生成代码

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


mkdir -p src/util/gen


运行以下命令,利用 protoc-gen-es、protoc-gen-apache-dubbo-es 等插件在 gen 目录下生成代码文件:


PATH=$PATH:$(pwd)/node_modules/.bin \
  protoc -I src/util/proto \
  --es_out src/util/gen \
  --es_opt target=ts \
  --apache-dubbo-es_out src/util/gen \
  --apache-dubbo-es_opt target=ts \
  example.proto


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


├── src
│   ├── util
│   │   ├── gen
│   │   │   ├── example_dubbo.ts
│   │   │   └── example_pb.ts
│   │   └── proto
│   │       └── example.proto


创建 App

需要先下载 @apachedubbo/dubbo-web。


npm install @apachedubbo/dubbo-web


现在我们可以从包中导入服务并设置一个客户端。在 App.tsx 中添加以下内容:


import { useState } from "react";
import "./App.css";
import { createPromiseClient } from "@apachedubbo/dubbo";
import { createDubboTransport } from "@apachedubbo/dubbo-web";
// Import service definition that you want to connect to.
import { ExampleService } from "./util/gen/example_dubbo";
// The transport defines what type of endpoint we're hitting.
// In our example we'll be communicating with a Dubbo endpoint.
const transport = createDubboTransport({
  baseUrl: "http://localhost:8080",
});
// Here we make the client itself, combining the service
// definition with the transport.
const client = createPromiseClient(ExampleService, transport, { serviceGroup: 'dubbo', serviceVersion: '1.0.0' });
function App() {
  const [inputValue, setInputValue] = useState("");
  const [messages, setMessages] = useState<
    {
      fromMe: boolean;
      message: string;
    }[]
  >([]);
  return (
    <>
      <ol>
        {messages.map((msg, index) => (
          <li key={index}>{`${msg.fromMe ? "ME:" : "Dubbo Server:"} ${msg.message}`}</li>
        ))}
      </ol>
      <form
        onSubmit={async (e) => {
          e.preventDefault();
          // Clear inputValue since the user has submitted.
          setInputValue("");
          // Store the inputValue in the chain of messages and
          // mark this message as coming from "me"
          setMessages((prev) => [
            ...prev,
            {
              fromMe: true,
              message: inputValue,
            },
          ]);
          const response = await client.say({
            sentence: inputValue,
          });
          setMessages((prev) => [
            ...prev,
            {
              fromMe: false,
              message: response.sentence,
            },
          ]);
        }}
      >
        <input value={inputValue} onChange={(e) => setInputValue(e.target.value)} />
        <button type="submit">Send</button>
      </form>
    </>
  );
}
export default App;


执行以下命令,即可得到样例页面。


npm run dev


启动 Server

接下来我们需要启动 Server,可以使用 Java、Go、Node.js 等 Dubbo 支持的任一语言开发 Server。这里我们采用 Dubbo 服务嵌入的 Node.js 服务器,具体可参考 Node.js 开发 Dubbo 后端服务[2]中的操作步骤。


不过需要注意,我们额外需要修改 Node.js 示例:引入 @fastify/cors 来解决前端请求的跨域问题。


npm install @fastify/cors


需要在 server.ts 文件下修改。


...
import cors from "@fastify/cors";
...
async function main() {
  const server = fastify();
  ...
  await server.register(cors, {
    origin: true,
  });
  ...
  await server.listen({ host: "localhost", port: 8080 });
  ...
}
void main();


最后,运行代码启动服务。


npx tsx server.ts


无 IDL 模式

在接下来的版本中,我们将继续提供无 IDL 模式的通信支持,这样就可以更方便的访问无 IDL 的后端服务。在这里,我们先快速的看一下无 IDL 模式的使用方式。


同样需要先安装 @apachedubbo/dubbo、@apachedubbo/dubbo-web。


npm install @apachedubbo/dubbo @apachedubbo/dubbo-web


现在就可以一个启动一个客户端,并发起调用了。App.tsx 中的代码与 IDL 模式基本一致,区别点在于以下内容:


// ...
// set backend server to connect
const transport = createDubboTransport({
  baseUrl: "http://localhost:8080",
});
// init client
const client = createPromiseClient(transport);
function App() {
  // ...
  // call remote Dubbo service
  const response = await client.call(
    "apache.dubbo.demo.example.v1.ExampleService", 
    "say", 
    {
      sentence: inputValue,
    });
}


执行以下命令,即可得到样例页面。


npm run dev


总结


直接在浏览器页面或 web 服务器中访问后端 Dubbo RPC 服务!Dubbo Triple 协议升级以及 Dubbo javascript sdk 的发布,对整个微服务体系是一个非常有力的补充,期待看到它能改变未来整个微服务架构以及前后端通信模式。


Dubbo-js 刚刚在 9 月份发布了支持 Dubbo3 Triple 协议的首个 alpha 版本,目前项目正处于快速发展中,对参与 apache/dubbo-js 项目感兴趣的开发者,欢迎通过以下方式加入组织:


  • 搜索钉钉群:29775027779 加入开发者群组。
  • 关注公众号「apachedubbo」回复 "dubbojs" 接受邀请加入开发组


相关链接:

[1] Dubbo TypeScript SDK

https://github.com/apache/dubbo-js/

[2] Node.js 开发 Dubbo 后端服务

https://github.com/apache/dubbo-js/tree/dubbo3/example/dubbo-node-example

相关文章
|
3天前
|
Web App开发 JavaScript 前端开发
深入浅出Node.js: 打造高效后端服务
【10月更文挑战第39天】在数字化浪潮中,后端开发作为支撑现代Web应用的骨架,扮演着不可或缺的角色。Node.js,作为一种流行的服务器端JavaScript运行环境,因其非阻塞I/O和事件驱动的特性,被广泛应用于构建轻量且高效的后端服务。本文旨在通过浅显易懂的语言,结合生动的比喻和实际代码案例,带领读者深入理解Node.js的核心概念、架构设计及其在后端开发中的应用,进而掌握如何使用Node.js搭建稳定、可扩展的后端服务。无论你是初探后端开发的新手,还是寻求进阶的开发者,这篇文章都将为你提供有价值的指导和启示。
|
5天前
|
运维 Prometheus 监控
如何在测试环境中保持操作系统、浏览器版本和服务器配置的稳定性和一致性?
如何在测试环境中保持操作系统、浏览器版本和服务器配置的稳定性和一致性?
|
8天前
|
Web App开发 JavaScript 前端开发
深入浅出Node.js后端框架
【10月更文挑战第34天】在数字化时代,后端开发如同一座桥梁,连接着用户界面与数据处理的两端。本文将通过Node.js这一轻量级、高效的平台,带领读者领略后端框架的魅力。我们将从基础概念出发,逐步深入到实战应用,最后探讨如何通过代码示例来巩固学习成果,使读者能够在理论与实践之间架起自己的桥梁。
|
1月前
|
JavaScript 前端开发 中间件
探索后端技术:Node.js与Express框架的完美融合
【10月更文挑战第7天】 在当今数字化时代,Web应用已成为日常生活不可或缺的一部分。本文将深入探讨后端技术的两大重要角色——Node.js和Express框架,分析它们如何通过其独特的特性和优势,为现代Web开发提供强大支持。我们将从Node.js的非阻塞I/O和事件驱动机制,到Express框架的简洁路由和中间件特性,全面解析它们的工作原理及应用场景。此外,本文还将分享一些实际开发中的小技巧,帮助你更有效地利用这些技术构建高效、可扩展的Web应用。无论你是刚入门的新手,还是经验丰富的开发者,相信这篇文章都能为你带来新的启发和思考。
|
1月前
|
JavaScript 前端开发 API
探索后端技术:Node.js的优势和实际应用
【10月更文挑战第6天】 在当今数字化时代,后端开发是任何成功软件应用的关键组成部分。本文将深入探讨一种流行的后端技术——Node.js,通过分析其核心优势和实际应用案例,揭示其在现代软件开发中的重要性和潜力。
118 2
|
13天前
|
前端开发 JavaScript
如何在 JavaScript 中访问和修改 CSS 变量?
【10月更文挑战第28天】通过以上方法,可以在JavaScript中灵活地访问和修改CSS变量,从而实现根据用户交互、页面状态等动态地改变页面样式,为网页添加更多的交互性和动态效果。在实际应用中,可以根据具体的需求和场景选择合适的方法来操作CSS变量。
|
14天前
|
JavaScript 中间件 关系型数据库
构建高效的后端服务:Node.js 与 Express 的实践指南
在后端开发领域,Node.js 与 Express 的组合因其轻量级和高效性而广受欢迎。本文将深入探讨如何利用这一组合构建高性能的后端服务。我们将从 Node.js 的事件驱动和非阻塞 I/O 模型出发,解释其如何优化网络请求处理。接着,通过 Express 框架的简洁 API,展示如何快速搭建 RESTful API。文章还将涉及中间件的使用,以及如何结合 MySQL 数据库进行数据操作。最后,我们将讨论性能优化技巧,包括异步编程模式和缓存策略,以确保服务的稳定性和扩展性。
|
6天前
|
Web App开发 JavaScript 前端开发
深入浅出Node.js后端开发
【10月更文挑战第36天】本文将引导您探索Node.js的世界,通过实际案例揭示其背后的原理和实践方法。从基础的安装到高级的异步处理,我们将一起构建一个简单的后端服务,并讨论如何优化性能。无论您是新手还是有经验的开发者,这篇文章都将为您提供新的视角和深入的理解。
|
11天前
|
Web App开发 存储 JavaScript
深入浅出Node.js后端开发
【10月更文挑战第31天】本文将引导你进入Node.js的奇妙世界,探索其如何革新后端开发。通过浅显易懂的语言和实际代码示例,我们将一起学习Node.js的核心概念、搭建开发环境,以及实现一个简单但完整的Web应用。无论你是编程新手还是希望拓展技术的开发者,这篇文章都将为你打开一扇通往高效后端开发的大门。
|
12天前
|
Web App开发 JavaScript 前端开发
深入浅出Node.js后端开发
【10月更文挑战第30天】本文将通过一个Node.js的简单示例,引导你进入Node.js的世界。我们将从基础概念讲起,然后一步步深入到代码实现,最后总结Node.js在后端开发中的优势和应用场景。无论你是前端开发者还是后端新手,这篇文章都将为你打开一扇了解Node.js的大门。
25 2