This is an automated email from the ASF dual-hosted git repository.

xuetaoli pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/dubbo-go-samples.git


The following commit(s) were added to refs/heads/main by this push:
     new e7d2f4fa feat: add openapi sample (#1063)
e7d2f4fa is described below

commit e7d2f4faca385386f10f93333b3c0f7487f19df3
Author: eye-gu <[email protected]>
AuthorDate: Mon Apr 13 13:28:40 2026 +0800

    feat: add openapi sample (#1063)
    
    * feat: add openapi sample
    
    * fix fmt
    
    * panic
    
    * fix ci
    
    * add doc
---
 README.md                                      |   1 +
 README_CN.md                                   |   1 +
 rpc/triple/openapi/README.md                   | 106 ++++++
 rpc/triple/openapi/README_CN.md                | 106 ++++++
 rpc/triple/openapi/go-client/cmd/main.go       | 103 ++++++
 rpc/triple/openapi/go-server/cmd/main.go       | 163 +++++++++
 rpc/triple/openapi/proto/demo/demo.pb.go       | 258 +++++++++++++
 rpc/triple/openapi/proto/demo/demo.proto       |  40 +++
 rpc/triple/openapi/proto/demo/demo.triple.go   | 129 +++++++
 rpc/triple/openapi/proto/greet/greet.pb.go     | 480 +++++++++++++++++++++++++
 rpc/triple/openapi/proto/greet/greet.proto     |  61 ++++
 rpc/triple/openapi/proto/greet/greet.triple.go | 393 ++++++++++++++++++++
 start_integrate_test.sh                        |   1 +
 13 files changed, 1842 insertions(+)

diff --git a/README.md b/README.md
index 4a30dc51..3b67a41e 100644
--- a/README.md
+++ b/README.md
@@ -64,6 +64,7 @@ Please refer to [HOWTO.md](HOWTO.md) for detailed 
instructions on running the sa
   * `rpc/grpc`: gRPC protocol example.
   * `rpc/jsonrpc`: JSON-RPC protocol example.
   * `rpc/triple`: Triple protocol example with multiple serialization formats.
+  * `rpc/triple/openapi`: Demonstrates how to enable OpenAPI documentation for 
Triple protocol services, including versioned services and non-IDL services.
 * `streaming`: Streaming RPC example, also includes Go–Java interoperability 
when both use streaming.
 * `task`: Task scheduling and execution example.
 * `timeout`: Demonstrates timeout handling in Dubbo-go.
diff --git a/README_CN.md b/README_CN.md
index f5f4bebd..05ae11d8 100644
--- a/README_CN.md
+++ b/README_CN.md
@@ -64,6 +64,7 @@
   * `rpc/grpc`:基于 gRPC 协议的示例。
   * `rpc/jsonrpc`:基于 JSON-RPC 协议的示例。
   * `rpc/triple`:Triple 协议示例,涵盖多种序列化方式。
+  * `rpc/triple/openapi`:演示如何为 Triple 协议服务启用 OpenAPI 文档,包括多版本服务和非 IDL 服务的注册。
 * `streaming`:流式 RPC 调用示例,并包含了Dubbo-go与Dubbo-java同时使用流式传输的互操作示例。
 * `task`:任务调度与执行示例。
 * `timeout`:Dubbo-go 超时处理示例。
diff --git a/rpc/triple/openapi/README.md b/rpc/triple/openapi/README.md
new file mode 100644
index 00000000..459e7714
--- /dev/null
+++ b/rpc/triple/openapi/README.md
@@ -0,0 +1,106 @@
+# Triple OpenAPI Sample
+
+English | [中文](README_CN.md)
+
+This sample demonstrates how to enable OpenAPI documentation for Triple 
protocol services in Dubbo-go. With OpenAPI enabled, the Triple server 
automatically generates and serves OpenAPI documentation in both JSON and YAML 
formats, and provides built-in Swagger UI and ReDoc pages for easy browsing and 
testing of your RPC services.
+
+## What It Covers
+
+- Enabling OpenAPI via `triple.OpenAPIEnable()` inside `triple.WithOpenAPI()`.
+- Registering multiple proto-based services (including streaming) with OpenAPI 
support.
+- Registering services with different versions and OpenAPI groups.
+- Registering a non-proto (non-IDL) service alongside proto-based services.
+
+## Contents
+
+- `go-server/cmd/main.go` - The server that enables OpenAPI and registers 
multiple services.
+- `go-client/cmd/main.go` - The client that calls the greet service (unary, 
server stream, client stream, bidi stream).
+- `proto/greet/greet.proto` - Protobuf definition with unary and streaming 
RPCs.
+- `proto/demo/demo.proto` - Protobuf definition for demonstrating versioned 
service registration.
+
+## How to Run
+
+### Start the Server
+
+```shell
+go run ./go-server/cmd/main.go
+```
+
+### Verify OpenAPI Documentation
+
+Once the server is running, you can access the OpenAPI documentation via the 
following URLs:
+
+| URL | Description |
+|-----|-------------|
+| `http://127.0.0.1:20000/dubbo/openapi/swagger-ui/` | Swagger UI page |
+| `http://127.0.0.1:20000/dubbo/openapi/openapi.json` | OpenAPI spec in JSON 
format |
+| `http://127.0.0.1:20000/dubbo/openapi/openapi.yaml` | OpenAPI spec in YAML 
format |
+| `http://127.0.0.1:20000/dubbo/openapi/api-docs/default.json` | Per-group 
OpenAPI spec (JSON) for the `default` group |
+| `http://127.0.0.1:20000/dubbo/openapi/api-docs/default.yaml` | Per-group 
OpenAPI spec (YAML) for the `default` group |
+| `http://127.0.0.1:20000/dubbo/openapi/redoc/index.html?group=default` | 
ReDoc documentation for the `default` group |
+
+For the `demo-2.0.0` group, replace `default` with `demo-2.0.0` in the URLs 
above.
+
+### Run the Client
+
+```shell
+go run ./go-client/cmd/main.go
+```
+
+## Configuration Reference
+
+### Server-side OpenAPI Configuration
+
+`triple.WithOpenAPI()` is the entry point for OpenAPI configuration. It 
accepts the following options:
+
+| Option | Description | Default |
+|--------|-------------|---------|
+| `triple.OpenAPIEnable()` | Enable OpenAPI documentation generation. 
**Required** to activate OpenAPI. | `false` |
+| `triple.OpenAPIInfoTitle(title)` | Title of the OpenAPI document. | 
`"Dubbo-go OpenAPI"` |
+| `triple.OpenAPIInfoDescription(desc)` | Description of the OpenAPI document. 
| `"Dubbo-go OpenAPI"` |
+| `triple.OpenAPIInfoVersion(version)` | Version of the OpenAPI document. | 
`"1.0.0"` |
+| `triple.OpenAPIPath(path)` | Base URL path for serving OpenAPI endpoints. | 
`"/dubbo/openapi"` |
+| `triple.OpenAPIDefaultConsumesMediaTypes(types...)` | Default request 
content types. | `["application/json"]` |
+| `triple.OpenAPIDefaultProducesMediaTypes(types...)` | Default response 
content types. | `["application/json"]` |
+| `triple.OpenAPIDefaultHttpStatusCodes(codes...)` | Default HTTP status codes 
for responses. | `["200", "400", "500"]` |
+| `triple.OpenAPISettings(settings)` | Additional key-value settings. | `{}` |
+
+Example:
+
+```go
+srv, err := server.NewServer(
+    server.WithServerProtocol(
+        protocol.WithTriple(
+            triple.WithOpenAPI(
+                triple.OpenAPIEnable(),
+                triple.OpenAPIInfoTitle("OpenAPI Service"),
+                triple.OpenAPIInfoDescription("A service with OpenAPI 
documentation"),
+                triple.OpenAPIInfoVersion("1.0.0"),
+            ),
+        ),
+        protocol.WithPort(20000),
+    ),
+)
+```
+
+### Service-level OpenAPI Group
+
+When registering a service, you can assign it to a specific OpenAPI group via 
`server.WithOpenAPIGroup()`:
+
+```go
+demo.RegisterGreetServiceHandler(srv, &DemoTripleServerV2{},
+    server.WithOpenAPIGroup("demo-2.0.0"),
+    server.WithVersion("2.0.0"),
+)
+```
+
+Services without an explicit group fall into the `default` group.
+
+### Services Registered in This Sample
+
+| Service | Description |
+|---------|-------------|
+| `greet.GreetService` | Unary + streaming RPCs (server stream, client stream, 
bidi stream) |
+| `demo.GreetService` (v1.0.0) | Unary RPC with version `1.0.0` |
+| `demo.GreetService` (v2.0.0) | Same interface with version `2.0.0`, 
registered under OpenAPI group `demo-2.0.0` |
+| `com.example.UserService` | Non-proto (non-IDL) service, registered without 
protobuf |
diff --git a/rpc/triple/openapi/README_CN.md b/rpc/triple/openapi/README_CN.md
new file mode 100644
index 00000000..adfe6d53
--- /dev/null
+++ b/rpc/triple/openapi/README_CN.md
@@ -0,0 +1,106 @@
+# Triple OpenAPI 示例
+
+[English](README.md) | 中文
+
+本示例演示如何在 Dubbo-go 中为 Triple 协议服务启用 OpenAPI 文档。启用 OpenAPI 后,Triple 服务端会自动生成并提供 
JSON 和 YAML 两种格式的 OpenAPI 文档,同时内置 Swagger UI 和 ReDoc 页面,方便浏览和测试 RPC 服务。
+
+## 功能说明
+
+- 通过 `triple.OpenAPIEnable()` 在 `triple.WithOpenAPI()` 中启用 OpenAPI 文档。
+- 注册多个基于 Protobuf 的服务(包括流式 RPC),并支持 OpenAPI 文档。
+- 注册不同版本的服务,并使用不同的 OpenAPI 分组。
+- 在基于 Protobuf 的服务之外,注册非 Protobuf(非 IDL)的服务。
+
+## 目录结构
+
+- `go-server/cmd/main.go` - 启用 OpenAPI 并注册多个服务的服务端。
+- `go-client/cmd/main.go` - 调用 Greet 服务的客户端(Unary、Server Stream、Client 
Stream、Bidi Stream)。
+- `proto/greet/greet.proto` - 包含 Unary 和流式 RPC 的 Protobuf 定义。
+- `proto/demo/demo.proto` - 用于演示多版本服务注册的 Protobuf 定义。
+
+## 运行方法
+
+### 启动服务端
+
+```shell
+go run ./go-server/cmd/main.go
+```
+
+### 验证 OpenAPI 文档
+
+服务启动后,可以通过以下地址访问 OpenAPI 文档:
+
+| URL | 说明 |
+|-----|------|
+| `http://127.0.0.1:20000/dubbo/openapi/swagger-ui/` | Swagger UI 页面 |
+| `http://127.0.0.1:20000/dubbo/openapi/openapi.json` | JSON 格式的 OpenAPI 规范 |
+| `http://127.0.0.1:20000/dubbo/openapi/openapi.yaml` | YAML 格式的 OpenAPI 规范 |
+| `http://127.0.0.1:20000/dubbo/openapi/api-docs/default.json` | `default` 分组的 
OpenAPI 规范(JSON) |
+| `http://127.0.0.1:20000/dubbo/openapi/api-docs/default.yaml` | `default` 分组的 
OpenAPI 规范(YAML) |
+| `http://127.0.0.1:20000/dubbo/openapi/redoc/index.html?group=default` | 
`default` 分组的 ReDoc 文档 |
+
+对于 `demo-2.0.0` 分组,将上述 URL 中的 `default` 替换为 `demo-2.0.0` 即可。
+
+### 启动客户端
+
+```shell
+go run ./go-client/cmd/main.go
+```
+
+## 配置说明
+
+### 服务端 OpenAPI 配置
+
+`triple.WithOpenAPI()` 是 OpenAPI 配置的入口,接受以下选项:
+
+| 选项 | 说明 | 默认值 |
+|------|------|--------|
+| `triple.OpenAPIEnable()` | 启用 OpenAPI 文档生成,**必须调用**才能激活 OpenAPI。 | `false` |
+| `triple.OpenAPIInfoTitle(title)` | OpenAPI 文档标题。 | `"Dubbo-go OpenAPI"` |
+| `triple.OpenAPIInfoDescription(desc)` | OpenAPI 文档描述。 | `"Dubbo-go OpenAPI"` 
|
+| `triple.OpenAPIInfoVersion(version)` | OpenAPI 文档版本。 | `"1.0.0"` |
+| `triple.OpenAPIPath(path)` | OpenAPI 端点的 URL 基础路径。 | `"/dubbo/openapi"` |
+| `triple.OpenAPIDefaultConsumesMediaTypes(types...)` | 默认请求内容类型。 | 
`["application/json"]` |
+| `triple.OpenAPIDefaultProducesMediaTypes(types...)` | 默认响应内容类型。 | 
`["application/json"]` |
+| `triple.OpenAPIDefaultHttpStatusCodes(codes...)` | 默认响应 HTTP 状态码。 | `["200", 
"400", "500"]` |
+| `triple.OpenAPISettings(settings)` | 额外的键值对配置。 | `{}` |
+
+示例:
+
+```go
+srv, err := server.NewServer(
+    server.WithServerProtocol(
+        protocol.WithTriple(
+            triple.WithOpenAPI(
+                triple.OpenAPIEnable(),
+                triple.OpenAPIInfoTitle("OpenAPI Service"),
+                triple.OpenAPIInfoDescription("A service with OpenAPI 
documentation"),
+                triple.OpenAPIInfoVersion("1.0.0"),
+            ),
+        ),
+        protocol.WithPort(20000),
+    ),
+)
+```
+
+### 服务级 OpenAPI 分组
+
+注册服务时,可以通过 `server.WithOpenAPIGroup()` 将服务分配到指定的 OpenAPI 分组:
+
+```go
+demo.RegisterGreetServiceHandler(srv, &DemoTripleServerV2{},
+    server.WithOpenAPIGroup("demo-2.0.0"),
+    server.WithVersion("2.0.0"),
+)
+```
+
+未显式指定分组的服务会归入 `default` 分组。
+
+### 本示例注册的服务
+
+| 服务 | 说明 |
+|------|------|
+| `greet.GreetService` | Unary + 流式 RPC(Server Stream、Client Stream、Bidi 
Stream) |
+| `demo.GreetService` (v1.0.0) | 版本为 `1.0.0` 的 Unary RPC |
+| `demo.GreetService` (v2.0.0) | 相同接口但版本为 `2.0.0`,注册在独立的 OpenAPI 分组 
`demo-2.0.0` 下 |
+| `com.example.UserService` | 非 Protobuf(非 IDL)服务,不依赖 Protobuf 定义 |
diff --git a/rpc/triple/openapi/go-client/cmd/main.go 
b/rpc/triple/openapi/go-client/cmd/main.go
new file mode 100644
index 00000000..d58d4131
--- /dev/null
+++ b/rpc/triple/openapi/go-client/cmd/main.go
@@ -0,0 +1,103 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package main
+
+import (
+       "context"
+       "fmt"
+       "strings"
+)
+
+import (
+       "dubbo.apache.org/dubbo-go/v3/client"
+       _ "dubbo.apache.org/dubbo-go/v3/imports"
+)
+
+import (
+       greet 
"github.com/apache/dubbo-go-samples/rpc/triple/openapi/proto/greet"
+)
+
+func main() {
+       cli, err := client.NewClient(
+               client.WithClientURL("127.0.0.1:20000"),
+       )
+       if err != nil {
+               panic(err)
+       }
+       svc, err := greet.NewGreetService(cli)
+       if err != nil {
+               panic(err)
+       }
+
+       // Unary
+       resp, err := svc.Greet(context.Background(), &greet.GreetRequest{Name: 
"openapi"})
+       if err != nil {
+               panic(err)
+       }
+       fmt.Printf("Greet response: %s\n", resp.Greeting)
+
+       // Server Stream
+       serverStream, err := svc.GreetServerStream(context.Background(), 
&greet.GreetServerStreamRequest{Name: "openapi"})
+       if err != nil {
+               panic(err)
+       }
+       for serverStream.Recv() {
+               msg := serverStream.Msg()
+               fmt.Printf("GreetServerStream response: %s\n", msg.Greeting)
+       }
+
+       // Client Stream
+       clientStream, err := svc.GreetClientStream(context.Background())
+       if err != nil {
+               panic(err)
+       }
+       for _, name := range []string{"alice", "bob", "charlie"} {
+               if sendErr := 
clientStream.Send(&greet.GreetClientStreamRequest{Name: name}); sendErr != nil {
+                       panic(sendErr)
+               }
+       }
+       clientResp, err := clientStream.CloseAndRecv()
+       if err != nil {
+               panic(err)
+       }
+       fmt.Printf("GreetClientStream response: %s\n", clientResp.Greeting)
+
+       // Bidi Stream
+       bidiStream, err := svc.GreetBidiStream(context.Background())
+       if err != nil {
+               panic(err)
+       }
+       for _, name := range []string{"dave", "eve"} {
+               if err := bidiStream.Send(&greet.GreetBidiStreamRequest{Name: 
name}); err != nil {
+                       panic(err)
+               }
+       }
+       if err := bidiStream.CloseRequest(); err != nil {
+               panic(err)
+       }
+       for {
+               msg, err := bidiStream.Recv()
+               if err != nil && strings.Contains(err.Error(), "EOF") {
+                       break
+               }
+               if err != nil {
+                       panic(err)
+               }
+               fmt.Printf("GreetBidiStream response: %s\n", msg.Greeting)
+       }
+}
diff --git a/rpc/triple/openapi/go-server/cmd/main.go 
b/rpc/triple/openapi/go-server/cmd/main.go
new file mode 100644
index 00000000..8a8a96c1
--- /dev/null
+++ b/rpc/triple/openapi/go-server/cmd/main.go
@@ -0,0 +1,163 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package main
+
+import (
+       "context"
+)
+
+import (
+       _ "dubbo.apache.org/dubbo-go/v3/imports"
+       "dubbo.apache.org/dubbo-go/v3/protocol"
+       triple "dubbo.apache.org/dubbo-go/v3/protocol/triple"
+       "dubbo.apache.org/dubbo-go/v3/server"
+)
+
+import (
+       demo "github.com/apache/dubbo-go-samples/rpc/triple/openapi/proto/demo"
+       greet 
"github.com/apache/dubbo-go-samples/rpc/triple/openapi/proto/greet"
+)
+
+type GreetTripleServer struct{}
+
+func (srv *GreetTripleServer) Greet(ctx context.Context, req 
*greet.GreetRequest) (*greet.GreetResponse, error) {
+       resp := &greet.GreetResponse{Greeting: "Hello, " + req.Name}
+       return resp, nil
+}
+
+func (srv *GreetTripleServer) GreetServerStream(ctx context.Context, req 
*greet.GreetServerStreamRequest, stream 
greet.GreetService_GreetServerStreamServer) error {
+       for i := 0; i < 5; i++ {
+               if err := 
stream.Send(&greet.GreetServerStreamResponse{Greeting: "Hello, " + req.Name}); 
err != nil {
+                       return err
+               }
+       }
+       return nil
+}
+
+func (srv *GreetTripleServer) GreetClientStream(ctx context.Context, stream 
greet.GreetService_GreetClientStreamServer) (*greet.GreetClientStreamResponse, 
error) {
+       var names []string
+       for stream.Recv() {
+
+               msg := stream.Msg()
+               names = append(names, msg.Name)
+       }
+       return &greet.GreetClientStreamResponse{Greeting: "Hello, " + 
joinNames(names)}, nil
+}
+
+func (srv *GreetTripleServer) GreetBidiStream(ctx context.Context, stream 
greet.GreetService_GreetBidiStreamServer) error {
+       for {
+               req, err := stream.Recv()
+               if err != nil {
+                       return err
+               }
+               if err := stream.Send(&greet.GreetBidiStreamResponse{Greeting: 
"Hello, " + req.Name}); err != nil {
+                       return err
+               }
+       }
+}
+
+func joinNames(names []string) string {
+       result := ""
+       for i, n := range names {
+               if i > 0 {
+                       result += ", "
+               }
+               result += n
+       }
+       return result
+}
+
+type DemoTripleServerV1 struct{}
+
+func (srv *DemoTripleServerV1) Greet(ctx context.Context, req 
*demo.GreetRequest) (*demo.GreetResponse, error) {
+       resp := &demo.GreetResponse{Greeting: "Hello, " + req.Name}
+       return resp, nil
+}
+
+type DemoTripleServerV2 struct{}
+
+func (srv *DemoTripleServerV2) Greet(ctx context.Context, req 
*demo.GreetRequest) (*demo.GreetResponse, error) {
+       resp := &demo.GreetResponse{Greeting: "Hello, " + req.Name}
+       return resp, nil
+}
+
+// Non-proto service (non-IDL mode)
+type UserService struct{}
+
+type UserRequest struct {
+       Id int32 `json:"id"`
+}
+
+type UserResponse struct {
+       Id   int32  `json:"id"`
+       Name string `json:"name"`
+       Age  int32  `json:"age"`
+}
+
+func (u *UserService) GetUser(ctx context.Context, req *UserRequest) 
(*UserResponse, error) {
+       return &UserResponse{
+               Id:   req.Id,
+               Name: "Alice",
+               Age:  30,
+       }, nil
+}
+
+func (u *UserService) Reference() string {
+       return "com.example.UserService"
+}
+
+func main() {
+       srv, err := server.NewServer(
+               server.WithServerProtocol(
+                       protocol.WithTriple(
+                               triple.WithOpenAPI(
+                                       triple.OpenAPIEnable(),
+                                       triple.OpenAPIInfoTitle("OpenAPI 
Service"),
+                                       triple.OpenAPIInfoDescription("A 
service with OpenAPI documentation"),
+                                       triple.OpenAPIInfoVersion("1.0.0"),
+                               ),
+                       ),
+                       protocol.WithPort(20000),
+               ),
+       )
+       if err != nil {
+               panic(err)
+       }
+       if registerErr := greet.RegisterGreetServiceHandler(srv, 
&GreetTripleServer{}); registerErr != nil {
+               panic(registerErr)
+       }
+       if registerErr := demo.RegisterGreetServiceHandler(srv, 
&DemoTripleServerV1{},
+               server.WithVersion("1.0.0"),
+       ); registerErr != nil {
+               panic(registerErr)
+       }
+       if registerErr := demo.RegisterGreetServiceHandler(srv, 
&DemoTripleServerV2{},
+               server.WithOpenAPIGroup("demo-2.0.0"),
+               server.WithVersion("2.0.0"),
+       ); registerErr != nil {
+               panic(registerErr)
+       }
+
+       if err := srv.RegisterService(&UserService{}); err != nil {
+               panic(err)
+       }
+
+       if err := srv.Serve(); err != nil {
+               panic(err)
+       }
+}
diff --git a/rpc/triple/openapi/proto/demo/demo.pb.go 
b/rpc/triple/openapi/proto/demo/demo.pb.go
new file mode 100644
index 00000000..027b7bef
--- /dev/null
+++ b/rpc/triple/openapi/proto/demo/demo.pb.go
@@ -0,0 +1,258 @@
+//
+// Licensed to the Apache Software Foundation (ASF) under one or more
+// contributor license agreements.  See the NOTICE file distributed with
+// this work for additional information regarding copyright ownership.
+// The ASF licenses this file to You under the Apache License, Version 2.0
+// (the "License"); you may not use this file except in compliance with
+// the License.  You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// Code generated by protoc-gen-go. DO NOT EDIT.
+// versions:
+//     protoc-gen-go v1.36.11
+//     protoc        v7.34.1
+// source: demo/demo.proto
+
+package demo
+
+import (
+       protoreflect "google.golang.org/protobuf/reflect/protoreflect"
+       protoimpl "google.golang.org/protobuf/runtime/protoimpl"
+       reflect "reflect"
+       sync "sync"
+       unsafe "unsafe"
+)
+
+const (
+       // Verify that this generated code is sufficiently up-to-date.
+       _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion)
+       // Verify that runtime/protoimpl is sufficiently up-to-date.
+       _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
+)
+
+type GreetRequest struct {
+       state         protoimpl.MessageState `protogen:"open.v1"`
+       Name          string                 
`protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"`
+       Node          *Node                  
`protobuf:"bytes,2,opt,name=node,proto3" json:"node,omitempty"`
+       unknownFields protoimpl.UnknownFields
+       sizeCache     protoimpl.SizeCache
+}
+
+func (x *GreetRequest) Reset() {
+       *x = GreetRequest{}
+       mi := &file_demo_demo_proto_msgTypes[0]
+       ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+       ms.StoreMessageInfo(mi)
+}
+
+func (x *GreetRequest) String() string {
+       return protoimpl.X.MessageStringOf(x)
+}
+
+func (*GreetRequest) ProtoMessage() {}
+
+func (x *GreetRequest) ProtoReflect() protoreflect.Message {
+       mi := &file_demo_demo_proto_msgTypes[0]
+       if x != nil {
+               ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+               if ms.LoadMessageInfo() == nil {
+                       ms.StoreMessageInfo(mi)
+               }
+               return ms
+       }
+       return mi.MessageOf(x)
+}
+
+// Deprecated: Use GreetRequest.ProtoReflect.Descriptor instead.
+func (*GreetRequest) Descriptor() ([]byte, []int) {
+       return file_demo_demo_proto_rawDescGZIP(), []int{0}
+}
+
+func (x *GreetRequest) GetName() string {
+       if x != nil {
+               return x.Name
+       }
+       return ""
+}
+
+func (x *GreetRequest) GetNode() *Node {
+       if x != nil {
+               return x.Node
+       }
+       return nil
+}
+
+type Node struct {
+       state         protoimpl.MessageState `protogen:"open.v1"`
+       Name          string                 
`protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"`
+       Child         *Node                  
`protobuf:"bytes,2,opt,name=child,proto3" json:"child,omitempty"`
+       unknownFields protoimpl.UnknownFields
+       sizeCache     protoimpl.SizeCache
+}
+
+func (x *Node) Reset() {
+       *x = Node{}
+       mi := &file_demo_demo_proto_msgTypes[1]
+       ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+       ms.StoreMessageInfo(mi)
+}
+
+func (x *Node) String() string {
+       return protoimpl.X.MessageStringOf(x)
+}
+
+func (*Node) ProtoMessage() {}
+
+func (x *Node) ProtoReflect() protoreflect.Message {
+       mi := &file_demo_demo_proto_msgTypes[1]
+       if x != nil {
+               ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+               if ms.LoadMessageInfo() == nil {
+                       ms.StoreMessageInfo(mi)
+               }
+               return ms
+       }
+       return mi.MessageOf(x)
+}
+
+// Deprecated: Use Node.ProtoReflect.Descriptor instead.
+func (*Node) Descriptor() ([]byte, []int) {
+       return file_demo_demo_proto_rawDescGZIP(), []int{1}
+}
+
+func (x *Node) GetName() string {
+       if x != nil {
+               return x.Name
+       }
+       return ""
+}
+
+func (x *Node) GetChild() *Node {
+       if x != nil {
+               return x.Child
+       }
+       return nil
+}
+
+type GreetResponse struct {
+       state         protoimpl.MessageState `protogen:"open.v1"`
+       Greeting      string                 
`protobuf:"bytes,1,opt,name=greeting,proto3" json:"greeting,omitempty"`
+       unknownFields protoimpl.UnknownFields
+       sizeCache     protoimpl.SizeCache
+}
+
+func (x *GreetResponse) Reset() {
+       *x = GreetResponse{}
+       mi := &file_demo_demo_proto_msgTypes[2]
+       ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+       ms.StoreMessageInfo(mi)
+}
+
+func (x *GreetResponse) String() string {
+       return protoimpl.X.MessageStringOf(x)
+}
+
+func (*GreetResponse) ProtoMessage() {}
+
+func (x *GreetResponse) ProtoReflect() protoreflect.Message {
+       mi := &file_demo_demo_proto_msgTypes[2]
+       if x != nil {
+               ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+               if ms.LoadMessageInfo() == nil {
+                       ms.StoreMessageInfo(mi)
+               }
+               return ms
+       }
+       return mi.MessageOf(x)
+}
+
+// Deprecated: Use GreetResponse.ProtoReflect.Descriptor instead.
+func (*GreetResponse) Descriptor() ([]byte, []int) {
+       return file_demo_demo_proto_rawDescGZIP(), []int{2}
+}
+
+func (x *GreetResponse) GetGreeting() string {
+       if x != nil {
+               return x.Greeting
+       }
+       return ""
+}
+
+var File_demo_demo_proto protoreflect.FileDescriptor
+
+const file_demo_demo_proto_rawDesc = "" +
+       "\n" +
+       "\x0fdemo/demo.proto\x12\x04demo\"B\n" +
+       "\fGreetRequest\x12\x12\n" +
+       "\x04name\x18\x01 \x01(\tR\x04name\x12\x1e\n" +
+       "\x04node\x18\x02 \x01(\v2\n" +
+       ".demo.NodeR\x04node\"<\n" +
+       "\x04Node\x12\x12\n" +
+       "\x04name\x18\x01 \x01(\tR\x04name\x12 \n" +
+       "\x05child\x18\x02 \x01(\v2\n" +
+       ".demo.NodeR\x05child\"+\n" +
+       "\rGreetResponse\x12\x1a\n" +
+       "\bgreeting\x18\x01 \x01(\tR\bgreeting2B\n" +
+       "\fGreetService\x122\n" +
+       
"\x05Greet\x12\x12.demo.GreetRequest\x1a\x13.demo.GreetResponse\"\x00BGZEgithub.com/apache/dubbo-go-samples/rpc/triple/openapi/proto/demo;demob\x06proto3"
+
+var (
+       file_demo_demo_proto_rawDescOnce sync.Once
+       file_demo_demo_proto_rawDescData []byte
+)
+
+func file_demo_demo_proto_rawDescGZIP() []byte {
+       file_demo_demo_proto_rawDescOnce.Do(func() {
+               file_demo_demo_proto_rawDescData = 
protoimpl.X.CompressGZIP(unsafe.Slice(unsafe.StringData(file_demo_demo_proto_rawDesc),
 len(file_demo_demo_proto_rawDesc)))
+       })
+       return file_demo_demo_proto_rawDescData
+}
+
+var file_demo_demo_proto_msgTypes = make([]protoimpl.MessageInfo, 3)
+var file_demo_demo_proto_goTypes = []any{
+       (*GreetRequest)(nil),  // 0: demo.GreetRequest
+       (*Node)(nil),          // 1: demo.Node
+       (*GreetResponse)(nil), // 2: demo.GreetResponse
+}
+var file_demo_demo_proto_depIdxs = []int32{
+       1, // 0: demo.GreetRequest.node:type_name -> demo.Node
+       1, // 1: demo.Node.child:type_name -> demo.Node
+       0, // 2: demo.GreetService.Greet:input_type -> demo.GreetRequest
+       2, // 3: demo.GreetService.Greet:output_type -> demo.GreetResponse
+       3, // [3:4] is the sub-list for method output_type
+       2, // [2:3] is the sub-list for method input_type
+       2, // [2:2] is the sub-list for extension type_name
+       2, // [2:2] is the sub-list for extension extendee
+       0, // [0:2] is the sub-list for field type_name
+}
+
+func init() { file_demo_demo_proto_init() }
+func file_demo_demo_proto_init() {
+       if File_demo_demo_proto != nil {
+               return
+       }
+       type x struct{}
+       out := protoimpl.TypeBuilder{
+               File: protoimpl.DescBuilder{
+                       GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
+                       RawDescriptor: 
unsafe.Slice(unsafe.StringData(file_demo_demo_proto_rawDesc), 
len(file_demo_demo_proto_rawDesc)),
+                       NumEnums:      0,
+                       NumMessages:   3,
+                       NumExtensions: 0,
+                       NumServices:   1,
+               },
+               GoTypes:           file_demo_demo_proto_goTypes,
+               DependencyIndexes: file_demo_demo_proto_depIdxs,
+               MessageInfos:      file_demo_demo_proto_msgTypes,
+       }.Build()
+       File_demo_demo_proto = out.File
+       file_demo_demo_proto_goTypes = nil
+       file_demo_demo_proto_depIdxs = nil
+}
diff --git a/rpc/triple/openapi/proto/demo/demo.proto 
b/rpc/triple/openapi/proto/demo/demo.proto
new file mode 100644
index 00000000..f1fd08f5
--- /dev/null
+++ b/rpc/triple/openapi/proto/demo/demo.proto
@@ -0,0 +1,40 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+syntax = "proto3";
+
+package demo;
+
+option go_package = 
"github.com/apache/dubbo-go-samples/rpc/triple/openapi/proto/demo;demo";
+
+message GreetRequest {
+  string name = 1;
+  Node node = 2;
+}
+
+message Node {
+  string name = 1;
+  Node child = 2;
+}
+
+message GreetResponse {
+  string greeting = 1;
+}
+
+service GreetService {
+  rpc Greet(GreetRequest) returns (GreetResponse) {}
+}
diff --git a/rpc/triple/openapi/proto/demo/demo.triple.go 
b/rpc/triple/openapi/proto/demo/demo.triple.go
new file mode 100644
index 00000000..27fae461
--- /dev/null
+++ b/rpc/triple/openapi/proto/demo/demo.triple.go
@@ -0,0 +1,129 @@
+// Code generated by protoc-gen-triple. DO NOT EDIT.
+//
+// Source: demo/demo.proto
+package demo
+
+import (
+       client "dubbo.apache.org/dubbo-go/v3/client"
+       common "dubbo.apache.org/dubbo-go/v3/common"
+       constant "dubbo.apache.org/dubbo-go/v3/common/constant"
+       triple_protocol 
"dubbo.apache.org/dubbo-go/v3/protocol/triple/triple_protocol"
+       server "dubbo.apache.org/dubbo-go/v3/server"
+)
+
+import (
+       "context"
+       "reflect"
+)
+
+import (
+       "dubbo.apache.org/dubbo-go/v3"
+)
+
+// This is a compile-time assertion to ensure that this generated file and the 
Triple package
+// are compatible. If you get a compiler error that this constant is not 
defined, this code was
+// generated with a version of Triple newer than the one compiled into your 
binary. You can fix the
+// problem by either regenerating this code with an older version of Triple or 
updating the Triple
+// version compiled into your binary.
+const _ = triple_protocol.IsAtLeastVersion0_1_0
+
+const (
+       // GreetServiceName is the fully-qualified name of the GreetService 
service.
+       GreetServiceName = "demo.GreetService"
+)
+
+// These constants are the fully-qualified names of the RPCs defined in this 
package. They're
+// exposed at runtime as procedure and as the final two segments of the HTTP 
route.
+//
+// Note that these are different from the fully-qualified method names used by
+// google.golang.org/protobuf/reflect/protoreflect. To convert from these 
constants to
+// reflection-formatted method names, remove the leading slash and convert the 
remaining slash to a
+// period.
+const (
+       // GreetServiceGreetProcedure is the fully-qualified name of the 
GreetService's Greet RPC.
+       GreetServiceGreetProcedure = "/demo.GreetService/Greet"
+)
+
+var (
+       _ GreetService = (*GreetServiceImpl)(nil)
+)
+
+// GreetService is a client for the demo.GreetService service.
+type GreetService interface {
+       Greet(ctx context.Context, req *GreetRequest, opts 
...client.CallOption) (*GreetResponse, error)
+}
+
+// NewGreetService constructs a client for the demo.GreetService service.
+func NewGreetService(cli *client.Client, opts ...client.ReferenceOption) 
(GreetService, error) {
+       conn, err := cli.DialWithInfo("demo.GreetService", 
&GreetService_ClientInfo, opts...)
+       if err != nil {
+               return nil, err
+       }
+       return &GreetServiceImpl{
+               conn: conn,
+       }, nil
+}
+
+func SetConsumerGreetService(srv common.RPCService) {
+       dubbo.SetConsumerServiceWithInfo(srv, &GreetService_ClientInfo)
+}
+
+// GreetServiceImpl implements GreetService.
+type GreetServiceImpl struct {
+       conn *client.Connection
+}
+
+func (c *GreetServiceImpl) Greet(ctx context.Context, req *GreetRequest, opts 
...client.CallOption) (*GreetResponse, error) {
+       resp := new(GreetResponse)
+       if err := c.conn.CallUnary(ctx, []interface{}{req}, resp, "Greet", 
opts...); err != nil {
+               return nil, err
+       }
+       return resp, nil
+}
+
+var GreetService_ClientInfo = client.ClientInfo{
+       InterfaceName: "demo.GreetService",
+       MethodNames:   []string{"Greet"},
+       ConnectionInjectFunc: func(dubboCliRaw interface{}, conn 
*client.Connection) {
+               dubboCli := dubboCliRaw.(*GreetServiceImpl)
+               dubboCli.conn = conn
+       },
+}
+
+// GreetServiceHandler is an implementation of the demo.GreetService service.
+type GreetServiceHandler interface {
+       Greet(context.Context, *GreetRequest) (*GreetResponse, error)
+}
+
+func RegisterGreetServiceHandler(srv *server.Server, hdlr GreetServiceHandler, 
opts ...server.ServiceOption) error {
+       return srv.Register(hdlr, &GreetService_ServiceInfo, opts...)
+}
+
+func SetProviderGreetService(srv common.RPCService) {
+       dubbo.SetProviderServiceWithInfo(srv, &GreetService_ServiceInfo)
+}
+
+var GreetService_ServiceInfo = server.ServiceInfo{
+       InterfaceName: "demo.GreetService",
+       ServiceType:   (*GreetServiceHandler)(nil),
+       Methods: []server.MethodInfo{
+               {
+                       Name: "Greet",
+                       Type: constant.CallUnary,
+                       ReqInitFunc: func() interface{} {
+                               return new(GreetRequest)
+                       },
+                       MethodFunc: func(ctx context.Context, args 
[]interface{}, handler interface{}) (interface{}, error) {
+                               req := args[0].(*GreetRequest)
+                               res, err := 
handler.(GreetServiceHandler).Greet(ctx, req)
+                               if err != nil {
+                                       return nil, err
+                               }
+                               return triple_protocol.NewResponse(res), nil
+                       },
+                       Meta: map[string]interface{}{
+                               "response.type": 
reflect.TypeOf(new(GreetResponse)),
+                       },
+               },
+       },
+}
diff --git a/rpc/triple/openapi/proto/greet/greet.pb.go 
b/rpc/triple/openapi/proto/greet/greet.pb.go
new file mode 100644
index 00000000..81945302
--- /dev/null
+++ b/rpc/triple/openapi/proto/greet/greet.pb.go
@@ -0,0 +1,480 @@
+//
+// Licensed to the Apache Software Foundation (ASF) under one or more
+// contributor license agreements.  See the NOTICE file distributed with
+// this work for additional information regarding copyright ownership.
+// The ASF licenses this file to You under the Apache License, Version 2.0
+// (the "License"); you may not use this file except in compliance with
+// the License.  You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// Code generated by protoc-gen-go. DO NOT EDIT.
+// versions:
+//     protoc-gen-go v1.36.11
+//     protoc        v7.34.1
+// source: proto/greet/greet.proto
+
+package greet
+
+import (
+       protoreflect "google.golang.org/protobuf/reflect/protoreflect"
+       protoimpl "google.golang.org/protobuf/runtime/protoimpl"
+       reflect "reflect"
+       sync "sync"
+       unsafe "unsafe"
+)
+
+const (
+       // Verify that this generated code is sufficiently up-to-date.
+       _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion)
+       // Verify that runtime/protoimpl is sufficiently up-to-date.
+       _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
+)
+
+type GreetRequest struct {
+       state         protoimpl.MessageState `protogen:"open.v1"`
+       Name          string                 
`protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"`
+       unknownFields protoimpl.UnknownFields
+       sizeCache     protoimpl.SizeCache
+}
+
+func (x *GreetRequest) Reset() {
+       *x = GreetRequest{}
+       mi := &file_proto_greet_greet_proto_msgTypes[0]
+       ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+       ms.StoreMessageInfo(mi)
+}
+
+func (x *GreetRequest) String() string {
+       return protoimpl.X.MessageStringOf(x)
+}
+
+func (*GreetRequest) ProtoMessage() {}
+
+func (x *GreetRequest) ProtoReflect() protoreflect.Message {
+       mi := &file_proto_greet_greet_proto_msgTypes[0]
+       if x != nil {
+               ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+               if ms.LoadMessageInfo() == nil {
+                       ms.StoreMessageInfo(mi)
+               }
+               return ms
+       }
+       return mi.MessageOf(x)
+}
+
+// Deprecated: Use GreetRequest.ProtoReflect.Descriptor instead.
+func (*GreetRequest) Descriptor() ([]byte, []int) {
+       return file_proto_greet_greet_proto_rawDescGZIP(), []int{0}
+}
+
+func (x *GreetRequest) GetName() string {
+       if x != nil {
+               return x.Name
+       }
+       return ""
+}
+
+type GreetResponse struct {
+       state         protoimpl.MessageState `protogen:"open.v1"`
+       Greeting      string                 
`protobuf:"bytes,1,opt,name=greeting,proto3" json:"greeting,omitempty"`
+       unknownFields protoimpl.UnknownFields
+       sizeCache     protoimpl.SizeCache
+}
+
+func (x *GreetResponse) Reset() {
+       *x = GreetResponse{}
+       mi := &file_proto_greet_greet_proto_msgTypes[1]
+       ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+       ms.StoreMessageInfo(mi)
+}
+
+func (x *GreetResponse) String() string {
+       return protoimpl.X.MessageStringOf(x)
+}
+
+func (*GreetResponse) ProtoMessage() {}
+
+func (x *GreetResponse) ProtoReflect() protoreflect.Message {
+       mi := &file_proto_greet_greet_proto_msgTypes[1]
+       if x != nil {
+               ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+               if ms.LoadMessageInfo() == nil {
+                       ms.StoreMessageInfo(mi)
+               }
+               return ms
+       }
+       return mi.MessageOf(x)
+}
+
+// Deprecated: Use GreetResponse.ProtoReflect.Descriptor instead.
+func (*GreetResponse) Descriptor() ([]byte, []int) {
+       return file_proto_greet_greet_proto_rawDescGZIP(), []int{1}
+}
+
+func (x *GreetResponse) GetGreeting() string {
+       if x != nil {
+               return x.Greeting
+       }
+       return ""
+}
+
+type GreetServerStreamRequest struct {
+       state         protoimpl.MessageState `protogen:"open.v1"`
+       Name          string                 
`protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"`
+       unknownFields protoimpl.UnknownFields
+       sizeCache     protoimpl.SizeCache
+}
+
+func (x *GreetServerStreamRequest) Reset() {
+       *x = GreetServerStreamRequest{}
+       mi := &file_proto_greet_greet_proto_msgTypes[2]
+       ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+       ms.StoreMessageInfo(mi)
+}
+
+func (x *GreetServerStreamRequest) String() string {
+       return protoimpl.X.MessageStringOf(x)
+}
+
+func (*GreetServerStreamRequest) ProtoMessage() {}
+
+func (x *GreetServerStreamRequest) ProtoReflect() protoreflect.Message {
+       mi := &file_proto_greet_greet_proto_msgTypes[2]
+       if x != nil {
+               ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+               if ms.LoadMessageInfo() == nil {
+                       ms.StoreMessageInfo(mi)
+               }
+               return ms
+       }
+       return mi.MessageOf(x)
+}
+
+// Deprecated: Use GreetServerStreamRequest.ProtoReflect.Descriptor instead.
+func (*GreetServerStreamRequest) Descriptor() ([]byte, []int) {
+       return file_proto_greet_greet_proto_rawDescGZIP(), []int{2}
+}
+
+func (x *GreetServerStreamRequest) GetName() string {
+       if x != nil {
+               return x.Name
+       }
+       return ""
+}
+
+type GreetServerStreamResponse struct {
+       state         protoimpl.MessageState `protogen:"open.v1"`
+       Greeting      string                 
`protobuf:"bytes,1,opt,name=greeting,proto3" json:"greeting,omitempty"`
+       unknownFields protoimpl.UnknownFields
+       sizeCache     protoimpl.SizeCache
+}
+
+func (x *GreetServerStreamResponse) Reset() {
+       *x = GreetServerStreamResponse{}
+       mi := &file_proto_greet_greet_proto_msgTypes[3]
+       ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+       ms.StoreMessageInfo(mi)
+}
+
+func (x *GreetServerStreamResponse) String() string {
+       return protoimpl.X.MessageStringOf(x)
+}
+
+func (*GreetServerStreamResponse) ProtoMessage() {}
+
+func (x *GreetServerStreamResponse) ProtoReflect() protoreflect.Message {
+       mi := &file_proto_greet_greet_proto_msgTypes[3]
+       if x != nil {
+               ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+               if ms.LoadMessageInfo() == nil {
+                       ms.StoreMessageInfo(mi)
+               }
+               return ms
+       }
+       return mi.MessageOf(x)
+}
+
+// Deprecated: Use GreetServerStreamResponse.ProtoReflect.Descriptor instead.
+func (*GreetServerStreamResponse) Descriptor() ([]byte, []int) {
+       return file_proto_greet_greet_proto_rawDescGZIP(), []int{3}
+}
+
+func (x *GreetServerStreamResponse) GetGreeting() string {
+       if x != nil {
+               return x.Greeting
+       }
+       return ""
+}
+
+type GreetClientStreamRequest struct {
+       state         protoimpl.MessageState `protogen:"open.v1"`
+       Name          string                 
`protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"`
+       unknownFields protoimpl.UnknownFields
+       sizeCache     protoimpl.SizeCache
+}
+
+func (x *GreetClientStreamRequest) Reset() {
+       *x = GreetClientStreamRequest{}
+       mi := &file_proto_greet_greet_proto_msgTypes[4]
+       ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+       ms.StoreMessageInfo(mi)
+}
+
+func (x *GreetClientStreamRequest) String() string {
+       return protoimpl.X.MessageStringOf(x)
+}
+
+func (*GreetClientStreamRequest) ProtoMessage() {}
+
+func (x *GreetClientStreamRequest) ProtoReflect() protoreflect.Message {
+       mi := &file_proto_greet_greet_proto_msgTypes[4]
+       if x != nil {
+               ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+               if ms.LoadMessageInfo() == nil {
+                       ms.StoreMessageInfo(mi)
+               }
+               return ms
+       }
+       return mi.MessageOf(x)
+}
+
+// Deprecated: Use GreetClientStreamRequest.ProtoReflect.Descriptor instead.
+func (*GreetClientStreamRequest) Descriptor() ([]byte, []int) {
+       return file_proto_greet_greet_proto_rawDescGZIP(), []int{4}
+}
+
+func (x *GreetClientStreamRequest) GetName() string {
+       if x != nil {
+               return x.Name
+       }
+       return ""
+}
+
+type GreetClientStreamResponse struct {
+       state         protoimpl.MessageState `protogen:"open.v1"`
+       Greeting      string                 
`protobuf:"bytes,1,opt,name=greeting,proto3" json:"greeting,omitempty"`
+       unknownFields protoimpl.UnknownFields
+       sizeCache     protoimpl.SizeCache
+}
+
+func (x *GreetClientStreamResponse) Reset() {
+       *x = GreetClientStreamResponse{}
+       mi := &file_proto_greet_greet_proto_msgTypes[5]
+       ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+       ms.StoreMessageInfo(mi)
+}
+
+func (x *GreetClientStreamResponse) String() string {
+       return protoimpl.X.MessageStringOf(x)
+}
+
+func (*GreetClientStreamResponse) ProtoMessage() {}
+
+func (x *GreetClientStreamResponse) ProtoReflect() protoreflect.Message {
+       mi := &file_proto_greet_greet_proto_msgTypes[5]
+       if x != nil {
+               ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+               if ms.LoadMessageInfo() == nil {
+                       ms.StoreMessageInfo(mi)
+               }
+               return ms
+       }
+       return mi.MessageOf(x)
+}
+
+// Deprecated: Use GreetClientStreamResponse.ProtoReflect.Descriptor instead.
+func (*GreetClientStreamResponse) Descriptor() ([]byte, []int) {
+       return file_proto_greet_greet_proto_rawDescGZIP(), []int{5}
+}
+
+func (x *GreetClientStreamResponse) GetGreeting() string {
+       if x != nil {
+               return x.Greeting
+       }
+       return ""
+}
+
+type GreetBidiStreamRequest struct {
+       state         protoimpl.MessageState `protogen:"open.v1"`
+       Name          string                 
`protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"`
+       unknownFields protoimpl.UnknownFields
+       sizeCache     protoimpl.SizeCache
+}
+
+func (x *GreetBidiStreamRequest) Reset() {
+       *x = GreetBidiStreamRequest{}
+       mi := &file_proto_greet_greet_proto_msgTypes[6]
+       ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+       ms.StoreMessageInfo(mi)
+}
+
+func (x *GreetBidiStreamRequest) String() string {
+       return protoimpl.X.MessageStringOf(x)
+}
+
+func (*GreetBidiStreamRequest) ProtoMessage() {}
+
+func (x *GreetBidiStreamRequest) ProtoReflect() protoreflect.Message {
+       mi := &file_proto_greet_greet_proto_msgTypes[6]
+       if x != nil {
+               ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+               if ms.LoadMessageInfo() == nil {
+                       ms.StoreMessageInfo(mi)
+               }
+               return ms
+       }
+       return mi.MessageOf(x)
+}
+
+// Deprecated: Use GreetBidiStreamRequest.ProtoReflect.Descriptor instead.
+func (*GreetBidiStreamRequest) Descriptor() ([]byte, []int) {
+       return file_proto_greet_greet_proto_rawDescGZIP(), []int{6}
+}
+
+func (x *GreetBidiStreamRequest) GetName() string {
+       if x != nil {
+               return x.Name
+       }
+       return ""
+}
+
+type GreetBidiStreamResponse struct {
+       state         protoimpl.MessageState `protogen:"open.v1"`
+       Greeting      string                 
`protobuf:"bytes,1,opt,name=greeting,proto3" json:"greeting,omitempty"`
+       unknownFields protoimpl.UnknownFields
+       sizeCache     protoimpl.SizeCache
+}
+
+func (x *GreetBidiStreamResponse) Reset() {
+       *x = GreetBidiStreamResponse{}
+       mi := &file_proto_greet_greet_proto_msgTypes[7]
+       ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+       ms.StoreMessageInfo(mi)
+}
+
+func (x *GreetBidiStreamResponse) String() string {
+       return protoimpl.X.MessageStringOf(x)
+}
+
+func (*GreetBidiStreamResponse) ProtoMessage() {}
+
+func (x *GreetBidiStreamResponse) ProtoReflect() protoreflect.Message {
+       mi := &file_proto_greet_greet_proto_msgTypes[7]
+       if x != nil {
+               ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+               if ms.LoadMessageInfo() == nil {
+                       ms.StoreMessageInfo(mi)
+               }
+               return ms
+       }
+       return mi.MessageOf(x)
+}
+
+// Deprecated: Use GreetBidiStreamResponse.ProtoReflect.Descriptor instead.
+func (*GreetBidiStreamResponse) Descriptor() ([]byte, []int) {
+       return file_proto_greet_greet_proto_rawDescGZIP(), []int{7}
+}
+
+func (x *GreetBidiStreamResponse) GetGreeting() string {
+       if x != nil {
+               return x.Greeting
+       }
+       return ""
+}
+
+var File_proto_greet_greet_proto protoreflect.FileDescriptor
+
+const file_proto_greet_greet_proto_rawDesc = "" +
+       "\n" +
+       "\x17proto/greet/greet.proto\x12\x05greet\"\"\n" +
+       "\fGreetRequest\x12\x12\n" +
+       "\x04name\x18\x01 \x01(\tR\x04name\"+\n" +
+       "\rGreetResponse\x12\x1a\n" +
+       "\bgreeting\x18\x01 \x01(\tR\bgreeting\".\n" +
+       "\x18GreetServerStreamRequest\x12\x12\n" +
+       "\x04name\x18\x01 \x01(\tR\x04name\"7\n" +
+       "\x19GreetServerStreamResponse\x12\x1a\n" +
+       "\bgreeting\x18\x01 \x01(\tR\bgreeting\".\n" +
+       "\x18GreetClientStreamRequest\x12\x12\n" +
+       "\x04name\x18\x01 \x01(\tR\x04name\"7\n" +
+       "\x19GreetClientStreamResponse\x12\x1a\n" +
+       "\bgreeting\x18\x01 \x01(\tR\bgreeting\",\n" +
+       "\x16GreetBidiStreamRequest\x12\x12\n" +
+       "\x04name\x18\x01 \x01(\tR\x04name\"5\n" +
+       "\x17GreetBidiStreamResponse\x12\x1a\n" +
+       "\bgreeting\x18\x01 \x01(\tR\bgreeting2\xd4\x02\n" +
+       "\fGreetService\x124\n" +
+       
"\x05Greet\x12\x13.greet.GreetRequest\x1a\x14.greet.GreetResponse\"\x00\x12Z\n" 
+
+       "\x11GreetServerStream\x12\x1f.greet.GreetServerStreamRequest\x1a 
.greet.GreetServerStreamResponse\"\x000\x01\x12Z\n" +
+       "\x11GreetClientStream\x12\x1f.greet.GreetClientStreamRequest\x1a 
.greet.GreetClientStreamResponse\"\x00(\x01\x12V\n" +
+       
"\x0fGreetBidiStream\x12\x1d.greet.GreetBidiStreamRequest\x1a\x1e.greet.GreetBidiStreamResponse\"\x00(\x010\x01BIZGgithub.com/apache/dubbo-go-samples/rpc/triple/openapi/proto/greet;greetb\x06proto3"
+
+var (
+       file_proto_greet_greet_proto_rawDescOnce sync.Once
+       file_proto_greet_greet_proto_rawDescData []byte
+)
+
+func file_proto_greet_greet_proto_rawDescGZIP() []byte {
+       file_proto_greet_greet_proto_rawDescOnce.Do(func() {
+               file_proto_greet_greet_proto_rawDescData = 
protoimpl.X.CompressGZIP(unsafe.Slice(unsafe.StringData(file_proto_greet_greet_proto_rawDesc),
 len(file_proto_greet_greet_proto_rawDesc)))
+       })
+       return file_proto_greet_greet_proto_rawDescData
+}
+
+var file_proto_greet_greet_proto_msgTypes = make([]protoimpl.MessageInfo, 8)
+var file_proto_greet_greet_proto_goTypes = []any{
+       (*GreetRequest)(nil),              // 0: greet.GreetRequest
+       (*GreetResponse)(nil),             // 1: greet.GreetResponse
+       (*GreetServerStreamRequest)(nil),  // 2: greet.GreetServerStreamRequest
+       (*GreetServerStreamResponse)(nil), // 3: greet.GreetServerStreamResponse
+       (*GreetClientStreamRequest)(nil),  // 4: greet.GreetClientStreamRequest
+       (*GreetClientStreamResponse)(nil), // 5: greet.GreetClientStreamResponse
+       (*GreetBidiStreamRequest)(nil),    // 6: greet.GreetBidiStreamRequest
+       (*GreetBidiStreamResponse)(nil),   // 7: greet.GreetBidiStreamResponse
+}
+var file_proto_greet_greet_proto_depIdxs = []int32{
+       0, // 0: greet.GreetService.Greet:input_type -> greet.GreetRequest
+       2, // 1: greet.GreetService.GreetServerStream:input_type -> 
greet.GreetServerStreamRequest
+       4, // 2: greet.GreetService.GreetClientStream:input_type -> 
greet.GreetClientStreamRequest
+       6, // 3: greet.GreetService.GreetBidiStream:input_type -> 
greet.GreetBidiStreamRequest
+       1, // 4: greet.GreetService.Greet:output_type -> greet.GreetResponse
+       3, // 5: greet.GreetService.GreetServerStream:output_type -> 
greet.GreetServerStreamResponse
+       5, // 6: greet.GreetService.GreetClientStream:output_type -> 
greet.GreetClientStreamResponse
+       7, // 7: greet.GreetService.GreetBidiStream:output_type -> 
greet.GreetBidiStreamResponse
+       4, // [4:8] is the sub-list for method output_type
+       0, // [0:4] is the sub-list for method input_type
+       0, // [0:0] is the sub-list for extension type_name
+       0, // [0:0] is the sub-list for extension extendee
+       0, // [0:0] is the sub-list for field type_name
+}
+
+func init() { file_proto_greet_greet_proto_init() }
+func file_proto_greet_greet_proto_init() {
+       if File_proto_greet_greet_proto != nil {
+               return
+       }
+       type x struct{}
+       out := protoimpl.TypeBuilder{
+               File: protoimpl.DescBuilder{
+                       GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
+                       RawDescriptor: 
unsafe.Slice(unsafe.StringData(file_proto_greet_greet_proto_rawDesc), 
len(file_proto_greet_greet_proto_rawDesc)),
+                       NumEnums:      0,
+                       NumMessages:   8,
+                       NumExtensions: 0,
+                       NumServices:   1,
+               },
+               GoTypes:           file_proto_greet_greet_proto_goTypes,
+               DependencyIndexes: file_proto_greet_greet_proto_depIdxs,
+               MessageInfos:      file_proto_greet_greet_proto_msgTypes,
+       }.Build()
+       File_proto_greet_greet_proto = out.File
+       file_proto_greet_greet_proto_goTypes = nil
+       file_proto_greet_greet_proto_depIdxs = nil
+}
diff --git a/rpc/triple/openapi/proto/greet/greet.proto 
b/rpc/triple/openapi/proto/greet/greet.proto
new file mode 100644
index 00000000..98d3c672
--- /dev/null
+++ b/rpc/triple/openapi/proto/greet/greet.proto
@@ -0,0 +1,61 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+syntax = "proto3";
+
+package greet;
+
+option go_package = 
"github.com/apache/dubbo-go-samples/rpc/triple/openapi/proto/greet;greet";
+
+message GreetRequest {
+  string name = 1;
+}
+
+message GreetResponse {
+  string greeting = 1;
+}
+
+message GreetServerStreamRequest {
+  string name = 1;
+}
+
+message GreetServerStreamResponse {
+  string greeting = 1;
+}
+
+message GreetClientStreamRequest {
+  string name = 1;
+}
+
+message GreetClientStreamResponse {
+  string greeting = 1;
+}
+
+message GreetBidiStreamRequest {
+  string name = 1;
+}
+
+message GreetBidiStreamResponse {
+  string greeting = 1;
+}
+
+service GreetService {
+  rpc Greet(GreetRequest) returns (GreetResponse) {}
+  rpc GreetServerStream(GreetServerStreamRequest) returns (stream 
GreetServerStreamResponse) {}
+  rpc GreetClientStream(stream GreetClientStreamRequest) returns 
(GreetClientStreamResponse) {}
+  rpc GreetBidiStream(stream GreetBidiStreamRequest) returns (stream 
GreetBidiStreamResponse) {}
+}
diff --git a/rpc/triple/openapi/proto/greet/greet.triple.go 
b/rpc/triple/openapi/proto/greet/greet.triple.go
new file mode 100644
index 00000000..9e7a5084
--- /dev/null
+++ b/rpc/triple/openapi/proto/greet/greet.triple.go
@@ -0,0 +1,393 @@
+// Code generated by protoc-gen-triple. DO NOT EDIT.
+//
+// Source: proto/greet/greet.proto
+package greet
+
+import (
+       client "dubbo.apache.org/dubbo-go/v3/client"
+       common "dubbo.apache.org/dubbo-go/v3/common"
+       constant "dubbo.apache.org/dubbo-go/v3/common/constant"
+       triple_protocol 
"dubbo.apache.org/dubbo-go/v3/protocol/triple/triple_protocol"
+       server "dubbo.apache.org/dubbo-go/v3/server"
+)
+
+import (
+       "context"
+       "net/http"
+       "reflect"
+)
+
+import (
+       "dubbo.apache.org/dubbo-go/v3"
+)
+
+// This is a compile-time assertion to ensure that this generated file and the 
Triple package
+// are compatible. If you get a compiler error that this constant is not 
defined, this code was
+// generated with a version of Triple newer than the one compiled into your 
binary. You can fix the
+// problem by either regenerating this code with an older version of Triple or 
updating the Triple
+// version compiled into your binary.
+const _ = triple_protocol.IsAtLeastVersion0_1_0
+
+const (
+       // GreetServiceName is the fully-qualified name of the GreetService 
service.
+       GreetServiceName = "greet.GreetService"
+)
+
+// These constants are the fully-qualified names of the RPCs defined in this 
package. They're
+// exposed at runtime as procedure and as the final two segments of the HTTP 
route.
+//
+// Note that these are different from the fully-qualified method names used by
+// google.golang.org/protobuf/reflect/protoreflect. To convert from these 
constants to
+// reflection-formatted method names, remove the leading slash and convert the 
remaining slash to a
+// period.
+const (
+       // GreetServiceGreetProcedure is the fully-qualified name of the 
GreetService's Greet RPC.
+       GreetServiceGreetProcedure = "/greet.GreetService/Greet"
+       // GreetServiceGreetServerStreamProcedure is the fully-qualified name 
of the GreetService's GreetServerStream RPC.
+       GreetServiceGreetServerStreamProcedure = 
"/greet.GreetService/GreetServerStream"
+       // GreetServiceGreetClientStreamProcedure is the fully-qualified name 
of the GreetService's GreetClientStream RPC.
+       GreetServiceGreetClientStreamProcedure = 
"/greet.GreetService/GreetClientStream"
+       // GreetServiceGreetBidiStreamProcedure is the fully-qualified name of 
the GreetService's GreetBidiStream RPC.
+       GreetServiceGreetBidiStreamProcedure = 
"/greet.GreetService/GreetBidiStream"
+)
+
+var (
+       _ GreetService = (*GreetServiceImpl)(nil)
+
+       _ GreetService_GreetServerStreamClient = 
(*GreetServiceGreetServerStreamClient)(nil)
+       _ GreetService_GreetClientStreamClient = 
(*GreetServiceGreetClientStreamClient)(nil)
+       _ GreetService_GreetBidiStreamClient   = 
(*GreetServiceGreetBidiStreamClient)(nil)
+
+       _ GreetService_GreetServerStreamServer = 
(*GreetServiceGreetServerStreamServer)(nil)
+       _ GreetService_GreetClientStreamServer = 
(*GreetServiceGreetClientStreamServer)(nil)
+       _ GreetService_GreetBidiStreamServer   = 
(*GreetServiceGreetBidiStreamServer)(nil)
+)
+
+// GreetService is a client for the greet.GreetService service.
+type GreetService interface {
+       Greet(ctx context.Context, req *GreetRequest, opts 
...client.CallOption) (*GreetResponse, error)
+       GreetServerStream(ctx context.Context, req *GreetServerStreamRequest, 
opts ...client.CallOption) (GreetService_GreetServerStreamClient, error)
+       GreetClientStream(ctx context.Context, opts ...client.CallOption) 
(GreetService_GreetClientStreamClient, error)
+       GreetBidiStream(ctx context.Context, opts ...client.CallOption) 
(GreetService_GreetBidiStreamClient, error)
+}
+
+// NewGreetService constructs a client for the greet.GreetService service.
+func NewGreetService(cli *client.Client, opts ...client.ReferenceOption) 
(GreetService, error) {
+       conn, err := cli.DialWithInfo("greet.GreetService", 
&GreetService_ClientInfo, opts...)
+       if err != nil {
+               return nil, err
+       }
+       return &GreetServiceImpl{
+               conn: conn,
+       }, nil
+}
+
+func SetConsumerGreetService(srv common.RPCService) {
+       dubbo.SetConsumerServiceWithInfo(srv, &GreetService_ClientInfo)
+}
+
+// GreetServiceImpl implements GreetService.
+type GreetServiceImpl struct {
+       conn *client.Connection
+}
+
+func (c *GreetServiceImpl) Greet(ctx context.Context, req *GreetRequest, opts 
...client.CallOption) (*GreetResponse, error) {
+       resp := new(GreetResponse)
+       if err := c.conn.CallUnary(ctx, []interface{}{req}, resp, "Greet", 
opts...); err != nil {
+               return nil, err
+       }
+       return resp, nil
+}
+
+func (c *GreetServiceImpl) GreetServerStream(ctx context.Context, req 
*GreetServerStreamRequest, opts ...client.CallOption) 
(GreetService_GreetServerStreamClient, error) {
+       stream, err := c.conn.CallServerStream(ctx, req, "GreetServerStream", 
opts...)
+       if err != nil {
+               return nil, err
+       }
+       rawStream := stream.(*triple_protocol.ServerStreamForClient)
+       return &GreetServiceGreetServerStreamClient{rawStream}, nil
+}
+
+func (c *GreetServiceImpl) GreetClientStream(ctx context.Context, opts 
...client.CallOption) (GreetService_GreetClientStreamClient, error) {
+       stream, err := c.conn.CallClientStream(ctx, "GreetClientStream", 
opts...)
+       if err != nil {
+               return nil, err
+       }
+       rawStream := stream.(*triple_protocol.ClientStreamForClient)
+       return &GreetServiceGreetClientStreamClient{rawStream}, nil
+}
+
+func (c *GreetServiceImpl) GreetBidiStream(ctx context.Context, opts 
...client.CallOption) (GreetService_GreetBidiStreamClient, error) {
+       stream, err := c.conn.CallBidiStream(ctx, "GreetBidiStream", opts...)
+       if err != nil {
+               return nil, err
+       }
+       rawStream := stream.(*triple_protocol.BidiStreamForClient)
+       return &GreetServiceGreetBidiStreamClient{rawStream}, nil
+}
+
+type GreetService_GreetServerStreamClient interface {
+       Recv() bool
+       ResponseHeader() http.Header
+       ResponseTrailer() http.Header
+       Msg() *GreetServerStreamResponse
+       Err() error
+       Conn() (triple_protocol.StreamingClientConn, error)
+       Close() error
+}
+
+type GreetServiceGreetServerStreamClient struct {
+       *triple_protocol.ServerStreamForClient
+}
+
+func (cli *GreetServiceGreetServerStreamClient) Recv() bool {
+       msg := new(GreetServerStreamResponse)
+       return cli.ServerStreamForClient.Receive(msg)
+}
+
+func (cli *GreetServiceGreetServerStreamClient) Msg() 
*GreetServerStreamResponse {
+       msg := cli.ServerStreamForClient.Msg()
+       if msg == nil {
+               return new(GreetServerStreamResponse)
+       }
+       return msg.(*GreetServerStreamResponse)
+}
+
+func (cli *GreetServiceGreetServerStreamClient) Conn() 
(triple_protocol.StreamingClientConn, error) {
+       return cli.ServerStreamForClient.Conn()
+}
+
+type GreetService_GreetClientStreamClient interface {
+       Spec() triple_protocol.Spec
+       Peer() triple_protocol.Peer
+       Send(*GreetClientStreamRequest) error
+       RequestHeader() http.Header
+       CloseAndRecv() (*GreetClientStreamResponse, error)
+       Conn() (triple_protocol.StreamingClientConn, error)
+}
+
+type GreetServiceGreetClientStreamClient struct {
+       *triple_protocol.ClientStreamForClient
+}
+
+func (cli *GreetServiceGreetClientStreamClient) Send(msg 
*GreetClientStreamRequest) error {
+       return cli.ClientStreamForClient.Send(msg)
+}
+
+func (cli *GreetServiceGreetClientStreamClient) CloseAndRecv() 
(*GreetClientStreamResponse, error) {
+       msg := new(GreetClientStreamResponse)
+       resp := triple_protocol.NewResponse(msg)
+       if err := cli.ClientStreamForClient.CloseAndReceive(resp); err != nil {
+               return nil, err
+       }
+       return msg, nil
+}
+
+func (cli *GreetServiceGreetClientStreamClient) Conn() 
(triple_protocol.StreamingClientConn, error) {
+       return cli.ClientStreamForClient.Conn()
+}
+
+type GreetService_GreetBidiStreamClient interface {
+       Spec() triple_protocol.Spec
+       Peer() triple_protocol.Peer
+       Send(*GreetBidiStreamRequest) error
+       RequestHeader() http.Header
+       CloseRequest() error
+       Recv() (*GreetBidiStreamResponse, error)
+       ResponseHeader() http.Header
+       ResponseTrailer() http.Header
+       CloseResponse() error
+}
+
+type GreetServiceGreetBidiStreamClient struct {
+       *triple_protocol.BidiStreamForClient
+}
+
+func (cli *GreetServiceGreetBidiStreamClient) Send(msg 
*GreetBidiStreamRequest) error {
+       return cli.BidiStreamForClient.Send(msg)
+}
+
+func (cli *GreetServiceGreetBidiStreamClient) Recv() 
(*GreetBidiStreamResponse, error) {
+       msg := new(GreetBidiStreamResponse)
+       if err := cli.BidiStreamForClient.Receive(msg); err != nil {
+               return nil, err
+       }
+       return msg, nil
+}
+
+var GreetService_ClientInfo = client.ClientInfo{
+       InterfaceName: "greet.GreetService",
+       MethodNames:   []string{"Greet", "GreetServerStream", 
"GreetClientStream", "GreetBidiStream"},
+       ConnectionInjectFunc: func(dubboCliRaw interface{}, conn 
*client.Connection) {
+               dubboCli := dubboCliRaw.(*GreetServiceImpl)
+               dubboCli.conn = conn
+       },
+}
+
+// GreetServiceHandler is an implementation of the greet.GreetService service.
+type GreetServiceHandler interface {
+       Greet(context.Context, *GreetRequest) (*GreetResponse, error)
+       GreetServerStream(context.Context, *GreetServerStreamRequest, 
GreetService_GreetServerStreamServer) error
+       GreetClientStream(context.Context, 
GreetService_GreetClientStreamServer) (*GreetClientStreamResponse, error)
+       GreetBidiStream(context.Context, GreetService_GreetBidiStreamServer) 
error
+}
+
+func RegisterGreetServiceHandler(srv *server.Server, hdlr GreetServiceHandler, 
opts ...server.ServiceOption) error {
+       return srv.Register(hdlr, &GreetService_ServiceInfo, opts...)
+}
+
+func SetProviderGreetService(srv common.RPCService) {
+       dubbo.SetProviderServiceWithInfo(srv, &GreetService_ServiceInfo)
+}
+
+type GreetService_GreetServerStreamServer interface {
+       Send(*GreetServerStreamResponse) error
+       ResponseHeader() http.Header
+       ResponseTrailer() http.Header
+       Conn() triple_protocol.StreamingHandlerConn
+}
+
+type GreetServiceGreetServerStreamServer struct {
+       *triple_protocol.ServerStream
+}
+
+func (g *GreetServiceGreetServerStreamServer) Send(msg 
*GreetServerStreamResponse) error {
+       return g.ServerStream.Send(msg)
+}
+
+type GreetService_GreetClientStreamServer interface {
+       Spec() triple_protocol.Spec
+       Peer() triple_protocol.Peer
+       Recv() bool
+       RequestHeader() http.Header
+       Msg() *GreetClientStreamRequest
+       Err() error
+       Conn() triple_protocol.StreamingHandlerConn
+}
+
+type GreetServiceGreetClientStreamServer struct {
+       *triple_protocol.ClientStream
+}
+
+func (srv *GreetServiceGreetClientStreamServer) Recv() bool {
+       msg := new(GreetClientStreamRequest)
+       return srv.ClientStream.Receive(msg)
+}
+
+func (srv *GreetServiceGreetClientStreamServer) Msg() 
*GreetClientStreamRequest {
+       msgRaw := srv.ClientStream.Msg()
+       if msgRaw == nil {
+               return new(GreetClientStreamRequest)
+       }
+       return msgRaw.(*GreetClientStreamRequest)
+}
+
+type GreetService_GreetBidiStreamServer interface {
+       Send(*GreetBidiStreamResponse) error
+       Recv() (*GreetBidiStreamRequest, error)
+       Spec() triple_protocol.Spec
+       Peer() triple_protocol.Peer
+       RequestHeader() http.Header
+       ResponseHeader() http.Header
+       ResponseTrailer() http.Header
+       Conn() triple_protocol.StreamingHandlerConn
+}
+
+type GreetServiceGreetBidiStreamServer struct {
+       *triple_protocol.BidiStream
+}
+
+func (srv *GreetServiceGreetBidiStreamServer) Send(msg 
*GreetBidiStreamResponse) error {
+       return srv.BidiStream.Send(msg)
+}
+
+func (srv GreetServiceGreetBidiStreamServer) Recv() (*GreetBidiStreamRequest, 
error) {
+       msg := new(GreetBidiStreamRequest)
+       if err := srv.BidiStream.Receive(msg); err != nil {
+               return nil, err
+       }
+       return msg, nil
+}
+
+var GreetService_ServiceInfo = server.ServiceInfo{
+       InterfaceName: "greet.GreetService",
+       ServiceType:   (*GreetServiceHandler)(nil),
+       Methods: []server.MethodInfo{
+               {
+                       Name: "Greet",
+                       Type: constant.CallUnary,
+                       ReqInitFunc: func() interface{} {
+                               return new(GreetRequest)
+                       },
+                       MethodFunc: func(ctx context.Context, args 
[]interface{}, handler interface{}) (interface{}, error) {
+                               req := args[0].(*GreetRequest)
+                               res, err := 
handler.(GreetServiceHandler).Greet(ctx, req)
+                               if err != nil {
+                                       return nil, err
+                               }
+                               return triple_protocol.NewResponse(res), nil
+                       },
+                       Meta: map[string]interface{}{
+                               "response.type": 
reflect.TypeOf(new(GreetResponse)),
+                       },
+               },
+               {
+                       Name: "GreetServerStream",
+                       Type: constant.CallServerStream,
+                       ReqInitFunc: func() interface{} {
+                               return new(GreetServerStreamRequest)
+                       },
+                       StreamInitFunc: func(baseStream interface{}) 
interface{} {
+                               return 
&GreetServiceGreetServerStreamServer{baseStream.(*triple_protocol.ServerStream)}
+                       },
+                       MethodFunc: func(ctx context.Context, args 
[]interface{}, handler interface{}) (interface{}, error) {
+                               req := args[0].(*GreetServerStreamRequest)
+                               stream := 
args[1].(GreetService_GreetServerStreamServer)
+                               if err := 
handler.(GreetServiceHandler).GreetServerStream(ctx, req, stream); err != nil {
+                                       return nil, err
+                               }
+                               return nil, nil
+                       },
+                       Meta: map[string]interface{}{
+                               "response.type": 
reflect.TypeOf(new(GreetServerStreamResponse)),
+                       },
+               },
+               {
+                       Name: "GreetClientStream",
+                       Type: constant.CallClientStream,
+                       StreamInitFunc: func(baseStream interface{}) 
interface{} {
+                               return 
&GreetServiceGreetClientStreamServer{baseStream.(*triple_protocol.ClientStream)}
+                       },
+                       MethodFunc: func(ctx context.Context, args 
[]interface{}, handler interface{}) (interface{}, error) {
+                               stream := 
args[0].(GreetService_GreetClientStreamServer)
+                               res, err := 
handler.(GreetServiceHandler).GreetClientStream(ctx, stream)
+                               if err != nil {
+                                       return nil, err
+                               }
+                               return triple_protocol.NewResponse(res), nil
+                       },
+                       Meta: map[string]interface{}{
+                               "request.type":  
reflect.TypeOf(new(GreetClientStreamRequest)),
+                               "response.type": 
reflect.TypeOf(new(GreetClientStreamResponse)),
+                       },
+               },
+               {
+                       Name: "GreetBidiStream",
+                       Type: constant.CallBidiStream,
+                       StreamInitFunc: func(baseStream interface{}) 
interface{} {
+                               return 
&GreetServiceGreetBidiStreamServer{baseStream.(*triple_protocol.BidiStream)}
+                       },
+                       MethodFunc: func(ctx context.Context, args 
[]interface{}, handler interface{}) (interface{}, error) {
+                               stream := 
args[0].(GreetService_GreetBidiStreamServer)
+                               if err := 
handler.(GreetServiceHandler).GreetBidiStream(ctx, stream); err != nil {
+                                       return nil, err
+                               }
+                               return nil, nil
+                       },
+                       Meta: map[string]interface{}{
+                               "request.type":  
reflect.TypeOf(new(GreetBidiStreamRequest)),
+                               "response.type": 
reflect.TypeOf(new(GreetBidiStreamResponse)),
+                       },
+               },
+       },
+}
diff --git a/start_integrate_test.sh b/start_integrate_test.sh
index 91200bc9..1eb5606f 100755
--- a/start_integrate_test.sh
+++ b/start_integrate_test.sh
@@ -67,6 +67,7 @@ array+=("rpc/triple/pb2")
 array+=("rpc/triple/reflection")
 array+=("rpc/triple/registry")
 array+=("rpc/triple/stream")
+array+=("rpc/triple/openapi")
 
 # tls
 array+=("tls")

Reply via email to