Community Blog Dubbo-js Alpha Version: Enabling Direct Access to Backend Microservices via Browsers

Dubbo-js Alpha Version: Enabling Direct Access to Backend Microservices via Browsers

This article introduces the Dubbo-js alpha version, which supports the Dubbo3 protocol.

By Jianyi Cai

Based on the Triple protocol defined by Dubbo3, you can easily develop RPC services that are compatible with browsers and gRPC. These services can run on both HTTP/1 and HTTP/2. The Dubbo TypeScript SDK [1] supports defining services in IDL-specific or programming language-specific ways and provides a set of lightweight APIs for publishing or calling these services.

Dubbo-js has released its first alpha version with support for the Dubbo3 protocol in September. This release presents an opportunity to completely transform the architecture and communication mode of frontend and backend microservices. It allows direct access to backend Dubbo and gRPC services in browser pages or web servers.


Example of Web Application Running on a Browser

This example demonstrates how to develop a web application that runs on a browser using dubbo-js. The web page will call a backend service developed by dubbo node.js and generate the page content. This example showcases both IDL-based and IDL-free encoding modes.


IDL-based Mode


First, we'll use Vite to generate our frontend project template, which has been built into all the feature support we'll need later.

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

As Protocol Buffer is used, you must first install code generation tools such as @bufbuild/protoc-gen-es, @bufbuild/protobuf, @apachedubbo/protoc-gen-apache-dubbo-es, and @apachedubbo/dubbo.

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

Use Proto to Define Services

Now, use Protocol Buffer (IDL) to define a Dubbo service.

Create the util/proto directory under src and generate a file.

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

Enter the following content:

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) {}

This file declares a service called ExampleService, and defines a Say method for this service along with its request parameters SayRequest and returned value SayResponse.

Generate Code

Create a gen directory as the target directory where the generated files are placed.

mkdir -p src/util/gen

Run the following command to generate code files under the gen directory by using plug-ins such as protoc-gen-es and protoc-gen-apache-dubbo-es:

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 \

After running the command, you should see the following generated files in the target directory:

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

Create an App

You need to download @apachedubbo/dubbo-web first.

npm install @apachedubbo/dubbo-web

Now you can import the service from the package and set up a client. Add the following content to 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 (
        {messages.map((msg, index) => (
          <li key={index}>{`${msg.fromMe ? "ME:" : "Dubbo Server:"} ${msg.message}`}</li>
        onSubmit={async (e) => {
          // Clear inputValue since the user has submitted.
          // Store the inputValue in the chain of messages and
          // mark this message as coming from "me"
          setMessages((prev) => [
              fromMe: true,
              message: inputValue,
          const response = await client.say({
            sentence: inputValue,
          setMessages((prev) => [
              fromMe: false,
              message: response.sentence,
        <input value={inputValue} onChange={(e) => setInputValue(e.target.value)} />
        <button type="submit">Send</button>

export default App;

Run the following command to obtain the sample page:

npm run dev

Start the Server

Next, you need to start the Server. You can use any programming language supported by Dubbo, such as Java, Go, and Node.js, to develop the Server. In this example, the Node.js server embedded in the Dubbo service is used. For more information, see Develop Dubbo backend services with Node.js [2].

However, it should be noted that you need to modify the Node.js example: introduce @fastify/cors to solve the cross-region problem of frontend requests.

npm install @fastify/cors

It needs to be modified in the server.ts file.

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();

Finally, run the code to start the service.

npx tsx server.ts

IDL-free Mode

In future releases, we will continue to provide support for IDL-free communication, making it easier to access backend services without IDL. Let's take a quick look at how to use the IDL-free mode.

Begin by installing @apachedubbo/dubbo and @apachedubbo/dubbo-web.

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

Now you can start one client at a time and make calls. The code in App.tsx is similar to the IDL-based mode, with a few differences:

// ...
// 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(
      sentence: inputValue,

Run the following command to obtain the sample page:

npm run dev


The upgrade of the Dubbo Triple protocol and the release of the Dubbo JavaScript SDK are powerful additions to the entire microservice system. We anticipate that they will bring significant changes to the architecture of microservices and the communication mode between frontend and backend in the future.


[1] Dubbo TypeScript SDK
[2] Develop Dubbo backend service with Node.js

0 1 0
Share on

You may also like


Related Products

  • Microservices Engine (MSE)

    MSE provides a fully managed registration and configuration center, and gateway and microservices governance capabilities.

    Learn More
  • Function Compute

    Alibaba Cloud Function Compute is a fully-managed event-driven compute service. It allows you to focus on writing and uploading code without the need to manage infrastructure such as servers.

    Learn More
  • Elastic High Performance Computing Solution

    High Performance Computing (HPC) and AI technology helps scientific research institutions to perform viral gene sequencing, conduct new drug research and development, and shorten the research and development cycle.

    Learn More
  • Quick Starts

    Deploy custom Alibaba Cloud solutions for business-critical scenarios with Quick Start templates.

    Learn More