> ## Documentation Index
> Fetch the complete documentation index at: https://docs.unla.amoylab.com/llms.txt
> Use this file to discover all available pages before exploring further.

# 网关代理配置

> 详细的 MCP Gateway 代理服务配置指南

## HTTP 服务代理配置

以下是HTTP服务代理的具体配置示例，包含了路由、工具等配置：

```yaml theme={null}
name: "mock-server"              # 代理服务名称，全局唯一
tenant: "default"                # 租户标识，用于多租户场景

# 路由配置
routers:
  - server: "mock-server"       # 服务名称
    prefix: "/gateway/user"         # 路由前缀，全局唯一，不可重复，建议按照服务或者领域+模块来区分前缀

    # CORS 配置
    cors:
      allowOrigins:             # 开发测试环境可全部开放，线上最好按需开放。（大部分MCP Client是不需要开放跨域的）
        - "*"
      allowMethods:             # 允许的请求方法，按需开放，对于MCP（SSE和Streamable）来说通常只需要这3个方法即可
        - "GET"
        - "POST"
        - "PUT"
        - "OPTIONS"
      allowHeaders:
        - "Content-Type"        # 必须允许的
        - "Authorization"       # 有鉴权需求的需要支持请求里携带此Key
        - "Mcp-Session-Id"      # 对于MCP来说，必须支持请求里携带这个Key，否则Streamable HTTP无法正常使用
        - "mcp-protocol-version" # MCP协议版本头，用于协议版本协商
      exposeHeaders:
        - "Mcp-Session-Id"      # 对于MCP来说，开启跨域的时候必须要暴露这个Key，否则Streamable HTTP无法正常使用
        - "mcp-protocol-version" # MCP协议版本头
      allowCredentials: true    # 是否增加 Access-Control-Allow-Credentials: true 这个Header

# 服务配置
servers:
  - name: "mock-server"               # 服务名称，需要与routers中的server保持一致
    description: "Mock User Service"  # 服务描述
    allowedTools:                     # 允许使用的工具列表（为tools的子集）
      - "register_user"
      - "get_user_by_email"
      - "update_user_preferences"
      - "update_user_avatar"
    config:                                           # 服务级别的配置，可以在tools中通过{{.Config}}引用
      Cookie: 123                                     # 写死的配置
      Authorization: 'Bearer {{ env "AUTH_TOKEN" }}'  # 从环境变量中获取的配置，用法是'{{ env "ENV_VAR_NAME" }}'

# 工具配置
tools:
  - name: "register_user"                                   # 工具名称
    description: "Register a new user"                      # 工具描述
    method: "POST"                                          # 请求目标（上游、后端）服务的HTTP方法
    endpoint: "http://localhost:5236/users"                 # 目标服务地址
    headers:                                                # 请求头配置，用于在请求目标服务时携带的请求头
      Content-Type: "application/json"                      # 写死的请求头
      Authorization: "{{.Config.Authorization}}"            # 使用服务配置中的值
      Cookie: "{{.Config.Cookie}}"                          # 使用服务配置中的值
    args:                         # 参数配置
      - name: "username"          # 参数名称
        position: "body"          # 参数位置：header, query, path, body, form-data
        required: true            # 参数是否必填
        type: "string"            # 参数类型
        description: "Username"   # 参数描述
        default: ""               # 默认值
      - name: "email"
        position: "body"
        required: true
        type: "string"
        description: "Email"
        default: ""
    requestBody: |-                       # 请求体模板，用于动态生成请求体，如：从参数（MCP的请求arguments）中提取的值
      {
        "username": "{{.Args.username}}",
        "email": "{{.Args.email}}"
      }
    responseBody: |-                      # 响应体模板，用于动态生成响应体，如：从响应中提取的值
      {
        "id": "{{.Response.Data.id}}",
        "username": "{{.Response.Data.username}}",
        "email": "{{.Response.Data.email}}",
        "createdAt": "{{.Response.Data.createdAt}}"
      }

  - name: "get_user_by_email"
    description: "Get user by email"
    method: "GET"
    endpoint: "http://localhost:5236/users/email/{{.Args.email}}"
    args:
      - name: "email"
        position: "path"
        required: true
        type: "string"
        description: "Email"
        default: ""
    responseBody: |-
      {
        "id": "{{.Response.Data.id}}",
        "username": "{{.Response.Data.username}}",
        "email": "{{.Response.Data.email}}",
        "createdAt": "{{.Response.Data.createdAt}}"
      }

  - name: "update_user_preferences"
    description: "Update user preferences"
    method: "PUT"
    endpoint: "http://localhost:5236/users/{{.Args.email}}/preferences"
    headers:
      Content-Type: "application/json"
      Authorization: "{{.Request.Headers.Authorization}}"
      Cookie: "{{.Config.Cookie}}"
    args:
      - name: "email"
        position: "path"
        required: true
        type: "string"
        description: "Email"
        default: ""
      - name: "isPublic"
        position: "body"
        required: true
        type: "boolean"
        description: "Whether the user profile is public"
        default: "false"
      - name: "showEmail"
        position: "body"
        required: true
        type: "boolean"
        description: "Whether to show email in profile"
        default: "true"
      - name: "theme"
        position: "body"
        required: true
        type: "string"
        description: "User interface theme"
        default: "light"
      - name: "tags"
        position: "body"
        required: true
        type: "array"
        items:
          type: "string"
          enum: ["developer", "designer", "manager", "tester"]
        description: "User role tags"
        default: "[]"
      - name: "settings"
        position: "body"
        required: false
        type: "object"
        description: "User custom settings as key-value pairs"
        default: "{}"
      - name: "notifications"
        position: "body"
        required: false
        type: "array"
        description: "User notification preferences"
        items:
          type: "object"
          properties:
            type:
              type: "string"
              description: "Notification type (email, push, sms)"
            channel:
              type: "string"
              description: "Notification channel (marketing, system, security)"
            enabled:
              type: "boolean"
              description: "Whether this notification is enabled"
            frequency:
              type: "number"
              description: "Notification frequency (0: realtime, 1: daily, 2: weekly, 3: monthly)"
        default: "[]"
    requestBody: |-
      {
        "isPublic": {{.Args.isPublic}},
        "showEmail": {{.Args.showEmail}},
        "theme": "{{.Args.theme}}",
        "tags": {{.Args.tags}},
        "settings": {{ toJSON .Args.settings }},
        "notifications": {{ .Args.notifications }}
      }
    responseBody: |-
      {
        "id": "{{.Response.Data.id}}",
        "username": "{{.Response.Data.username}}",
        "email": "{{.Response.Data.email}}",
        "createdAt": "{{.Response.Data.createdAt}}",
        "preferences": {
          "isPublic": {{.Response.Data.preferences.isPublic}},
          "showEmail": {{.Response.Data.preferences.showEmail}},
          "theme": "{{.Response.Data.preferences.theme}}",
          "tags": {{.Response.Data.preferences.tags}},
          "settings": {{ toJSON .Response.Data.preferences.settings }},
          "notifications": {{ toJSON .Response.Data.preferences.notifications }}
        }
      }

  - name: "update_user_avatar"
    description: "Update user avatar using a URL via multipart form"
    method: "POST"
    endpoint: "http://localhost:5236/users/{{.Args.email}}/avatar"
    headers:
      Authorization: "{{.Request.Headers.Authorization}}"
      Cookie: "{{.Config.Cookie}}"
    args:
      - name: "email"
        position: "path"
        required: true
        type: "string"
        description: "Email of the user"
        default: ""
      - name: "url"
        position: "form-data"
        required: true
        type: "string"
        description: "The avatar image URL"
        default: ""
    responseBody: |-
      {
        "message": "{{.Response.Data.message}}",
        "avatarUrl": "{{.Response.Data.avatarUrl}}"
      }
```

## 配置说明

### 1. 基础配置

<AccordionGroup>
  <Accordion icon="gear" title="port">
    MCP Gateway 服务监听端口，默认 5235
  </Accordion>

  <Accordion icon="file" title="pid">
    进程ID文件路径，用于进程管理和重载
  </Accordion>

  <Accordion icon="clock" title="reload_interval">
    配置重载间隔时间，默认 600s
  </Accordion>

  <Accordion icon="toggle" title="reload_switch">
    是否开启配置自动重载功能
  </Accordion>
</AccordionGroup>

可以把一份配置当作一个命名空间，建议按照服务或者领域来区分，某个服务里包含很多API接口，每个API接口对应一个Tool

* `name`: 代理服务名称，全局唯一，用于标识不同的代理服务
* `tenant`: 租户标识，用于多租户场景的数据隔离和权限管理

### 2. 路由配置

路由配置用于定义请求的转发规则：

```yaml theme={null}
routers:
  - server: "mock-server"       # 服务名称，需要与servers中的name保持一致
    prefix: "/gateway/user"         # 路由前缀，全局唯一，不可重复
```

目前默认情况下会在`prefix`的基础之上衍生出3个接入点：

* SSE: `${prefix}/sse`，如：`/gateway/user/sse`
* SSE: `${prefix}/message`，如：`/gateway/user/message`
* StreamableHTTP: `${prefix}/mcp`，如：`/gateway/user/mcp`

### 3. CORS配置

跨域资源共享（CORS）配置用于控制跨域请求的访问权限：

```yaml theme={null}
cors:
  allowOrigins:             # 开发测试环境可全部开放，线上最好按需开放。（大部分MCP Client是不需要开放跨域的）
    - "*"
  allowMethods:             # 允许的请求方法，按需开放，对于MCP（SSE和Streamable）来说通常只需要这3个方法即可
    - "GET"
    - "POST"
    - "OPTIONS"
  allowHeaders:
    - "Content-Type"        # 必须允许的
    - "Authorization"       # 有鉴权需求的需要支持请求里携带此Key
    - "Mcp-Session-Id"      # 对于MCP来说，必须支持请求里携带这个Key，否则Streamable HTTP无法正常使用
  exposeHeaders:
    - "Mcp-Session-Id"      # 对于MCP来说，开启跨域的时候必须要暴露这个Key，否则Streamable HTTP无法正常使用
  allowCredentials: true    # 是否增加 Access-Control-Allow-Credentials: true 这个Header
```

<Warning>
  通常情况下，MCP Client是不需要开放跨域的
</Warning>

### 4. 服务配置

服务配置用于定义服务元信息、关联的工具列表，以及服务级别的配置

```yaml theme={null}
servers:
  - name: "mock-server"               # 服务名称，需要与routers中的server保持一致
    namespace: "user-service"         # 服务命名空间，用于服务分组
    description: "Mock User Service"  # 服务描述
    allowedTools:                     # 允许使用的工具列表（为tools的子集）
      - "register_user"
      - "get_user_by_email"
      - "update_user_preferences"
    config:                                           # 服务级别的配置，可以在tools中通过{{.Config}}引用
      Cookie: 123                                     # 写死的配置
      Authorization: 'Bearer {{ env "AUTH_TOKEN" }}'  # 从环境变量中获取的配置，用法是'{{ env "ENV_VAR_NAME" }}'
```

服务级别的配置，可以在tools中通过 `{{.Config}}` 引用。此处可以通过写死在配置文件里的方式，也可以通过从环境变量中获取的方式。通过环境变量注入的话，需要通过`{{ env "ENV_VAR_NAME" }}`的方式引用

### 5. 工具配置

工具配置用于定义具体的API调用规则，每个参数都可以设置默认值（default），当MCP请求中没有提供该参数时，将自动使用默认值。

#### 5.1 请求参数组装

请求目标服务的时候会涉及组装参数的动作，目前有几个来源：

1. `.Config`: 从服务级别的配置中提取值
2. `.Args`: 直接从请求参数中提取值
3. `.Request`: 从请求中提取的值，包括请求头`.Request.Headers`、请求体`.Request.Body`等

参数位置（position）支持以下几种：

* `header`: 参数将被放置在请求头中
* `query`: 参数将被放置在URL查询字符串中
* `path`: 参数将被放置在URL路径中
* `body`: 参数将被放置在JSON格式的请求体中
* `form-data`: 参数将被放置在multipart/form-data格式的请求体中，用于文件上传等场景

参数类型（type）支持以下几种：

* `string`: 字符串类型
* `number`: 数字类型
* `boolean`: 布尔类型
* `array`: 数组类型，需要配合 `items` 定义数组元素类型
* `object`: 对象类型，可以使用 `properties` 定义对象结构

对于复杂的 `array` 类型参数，可以定义详细的元素结构：

```yaml theme={null}
- name: "notifications"
  position: "body"
  required: false
  type: "array"
  description: "User notification preferences"
  items:
    type: "object"
    properties:
      type:
        type: "string"
        description: "Notification type (email, push, sms)"
      enabled:
        type: "boolean"
        description: "Whether this notification is enabled"
  default: "[]"
```

当使用 `form-data` 作为参数位置时，不需要指定 `requestBody`，系统会自动将参数组装成 multipart/form-data 格式。

另外：`header` 和 `query` 参数也会被自动注入到下游请求中（Header 的键名等于参数名，Query 以 URL 查询字符串形式追加）。例如：

```yaml theme={null}
args:
  - name: "username"   # 发送 Header: Username: <值>
    position: "header"
  - name: "traceId"    # URL 追加 ?traceId=<值>
    position: "query"
```

<CardGroup cols={3}>
  <Card title="Client（MCP 请求）" icon="terminal">
    请求 arguments 示例（来自 MCP 客户端）：

    ```json theme={null}
    {
      "username": "alice",
      "traceId": "t-123",
      "avatarUrl": "https://img.example.com/1.png"
    }
    ```
  </Card>

  <Card title="MCP Gateway" icon="api">
    * `header` 自动写入下游 Header（键名=参数名）
    * `query` 自动追加到 URL 查询字符串
    * `form-data` 自动组装 multipart/form-data

    工具配置片段：

    ```yaml theme={null}
    tools:
      - name: demo
        method: POST
        endpoint: http://example.com/api/users
        args:
          - name: username   # Header: Username: alice
            position: header
          - name: traceId    # URL: ?traceId=t-123
            position: query
          - name: avatarUrl  # form field: avatarUrl=...
            position: form-data
    ```
  </Card>

  <Card title="下游服务（HTTP 请求）" icon="globe">
    实际发送给下游的请求：

    ```http theme={null}
    POST /api/users?traceId=t-123 HTTP/1.1
    Host: example.com
    Username: alice
    Content-Type: multipart/form-data; boundary=---BOUNDARY

    ---BOUNDARY
    Content-Disposition: form-data; name="avatarUrl"

    https://img.example.com/1.png
    ---BOUNDARY--
    ```
  </Card>
</CardGroup>

对于JSON格式的请求体，需要在 `requestBody` 中组装，比如：

```yaml theme={null}
    requestBody: |-
      {
        "isPublic": {{.Args.isPublic}},
        "showEmail": {{.Args.showEmail}},
        "theme": "{{.Args.theme}}",
        "tags": {{.Args.tags}}
      }
```

包括 `endpoint` 即目标地址也可以使用以上的来源去提取值，比如 `http://localhost:5236/users/{{.Args.email}}/preferences` 就是从请求参数中提取的值

#### 5.2 响应参数组装

响应体的组装和请求体的组装类似：

1. `.Response.Data`: 从响应中提取的值，响应必须是JSON的格式才可以提取
2. `.Response.Body`: 直接透传整个响应体，会忽略响应内容格式，直接传递给客户端

都是通过 `.Response` 来提取值，比如：

```yaml theme={null}
    responseBody: |-
      {
        "id": "{{.Response.Data.id}}",
        "username": "{{.Response.Data.username}}",
        "email": "{{.Response.Data.email}}",
        "createdAt": "{{.Response.Data.createdAt}}"
      }
```

## 配置存储

网关代理配置可以通过以下两种方式存储：

<CardGroup cols={2}>
  <Card title="数据库存储（推荐）" icon="database">
    * 支持 SQLite3、PostgreSQL、MySQL
    * 每个配置作为一条记录存储
    * 支持动态更新和热重载
  </Card>

  <Card title="文件存储" icon="folder">
    * 每个配置单独存储为一个 YAML 文件
    * 类似 Nginx 的 vhost 配置方式
    * 文件名建议使用服务名称，如 `mock-server.yaml`
  </Card>
</CardGroup>

## MCP 服务代理配置

除了代理 HTTP 服务外，MCP Gateway 还支持代理 MCP 服务，目前 stdio、SSE 和 streamable-http 三种传输协议都已支持

### 配置示例

以下是一个完整的 MCP 服务代理配置示例：

```yaml theme={null}
name: "proxy-mcp-exp"
tenant: "default"

routers:
  - server: "amap-maps"
    prefix: "/gateway/stdio-proxy"
    cors:
      allowOrigins:
        - "*"
      allowMethods:
        - "GET"
        - "POST"
        - "OPTIONS"
      allowHeaders:
        - "Content-Type"
        - "Authorization"
        - "Mcp-Session-Id"
      exposeHeaders:
        - "Mcp-Session-Id"
      allowCredentials: true
  - server: "mock-user-sse"
    prefix: "/gateway/sse-proxy"
    cors:
      allowOrigins:
        - "*"
      allowMethods:
        - "GET"
        - "POST"
        - "OPTIONS"
      allowHeaders:
        - "Content-Type"
        - "Authorization"
        - "Mcp-Session-Id"
      exposeHeaders:
        - "Mcp-Session-Id"
      allowCredentials: true
  - server: "mock-user-mcp"
    prefix: "/gateway/streamable-http-proxy"
    cors:
      allowOrigins:
        - "*"
      allowMethods:
        - "GET"
        - "POST"
        - "OPTIONS"
      allowHeaders:
        - "Content-Type"
        - "Authorization"
        - "Mcp-Session-Id"
      exposeHeaders:
        - "Mcp-Session-Id"
      allowCredentials: true

mcpServers:
  - type: "stdio"
    name: "amap-maps"
    command: "npx"
    args:
      - "-y"
      - "@amap/amap-maps-mcp-server"
    env:
      AMAP_MAPS_API_KEY: "{{.Request.Headers.Apikey}}"

  - type: "sse"
    name: "mock-user-sse"
    url: "http://localhost:3000/gateway/user/sse"

  - type: "streamable-http"
    name: "mock-user-mcp"
    url: "http://localhost:3000/gateway/user/mcp"
```

### 配置说明

#### 1. MCP 服务类型

MCP Gateway 支持以下三种类型的 MCP 服务代理：

<AccordionGroup>
  <Accordion icon="terminal" title="stdio 类型">
    * 通过标准输入输出与 MCP 服务进程通信
    * 适用于需要本地启动的 MCP 服务，如第三方 SDK
    * 配置参数包括 `command`、`args` 和 `env`
  </Accordion>

  <Accordion icon="stream" title="SSE 类型">
    * 将 MCP 客户端的请求转发到支持 SSE 的上游服务
    * 适用于已有的支持 SSE 协议的 MCP 服务
    * 仅需配置 `url` 参数指向上游 SSE 服务地址
  </Accordion>

  <Accordion icon="globe" title="streamable-http 类型">
    * 将 MCP 客户端的请求转发到支持可流式 HTTP 的上游服务
    * 适用于已有的支持 MCP 协议的上游服务
    * 仅需配置 `url` 参数指向上游 MCP 服务地址
  </Accordion>
</AccordionGroup>

#### 2. stdio 类型配置

stdio 类型的 MCP 服务配置示例：

```yaml theme={null}
mcpServers:
  - type: "stdio"
    name: "amap-maps"                                   # 服务名称
    command: "npx"                                      # 要执行的命令
    args:                                               # 命令参数
      - "-y"
      - "@amap/amap-maps-mcp-server"
    env:                                                # 环境变量
      AMAP_MAPS_API_KEY: "{{.Request.Headers.Apikey}}"  # 从请求头中提取值
```

通过 `env` 字段可以设置环境变量，支持从请求中提取值，例如 `{{.Request.Headers.Apikey}}` 表示从请求头中提取 Apikey 的值

#### 3. SSE 类型配置

SSE 类型的 MCP 服务配置示例：

```yaml theme={null}
mcpServers:
  - type: "sse"
    name: "mock-user-sse"                           # 服务名称
    url: "http://localhost:3000/gateway/user/sse"   # 上游 SSE 服务地址，通常以/sse结尾，实际根据上游服务而定
```

#### 4. streamable-http 类型配置

streamable-http 类型的 MCP 服务配置示例：

```yaml theme={null}
mcpServers:
  - type: "streamable-http"
    name: "mock-user-mcp"                           # 服务名称
    url: "http://localhost:3000/gateway/user/mcp"   # 上游 MCP 服务地址，通常以/mcp结尾，实际根据上游服务而定
```

#### 5. 路由配置

对于 MCP 服务代理，路由配置与 HTTP 服务代理类似，CORS 则根据实际情况配置（通常生产环境一般是不会开启跨域的）：

```yaml theme={null}
routers:
  - server: "amap-maps"               # 服务名称，需要与 mcpServers 中的 name 保持一致
    prefix: "/gateway/stdio-proxy"    # 路由前缀，全局唯一
    cors:
      allowOrigins:
        - "*"
      allowMethods:
        - "GET"
        - "POST"
        - "OPTIONS"
      allowHeaders:
        - "Content-Type"
        - "Authorization"
        - "Mcp-Session-Id"        # MCP 服务必须包含此头
      exposeHeaders:
        - "Mcp-Session-Id"        # MCP 服务必须暴露此头
      allowCredentials: true
```

<Warning>
  对于 MCP 服务，请求头和响应头中的 `Mcp-Session-Id` 是必须要支持的，否则客户端无法正常使用。
</Warning>

## 高级配置

### 通知器配置

通知器用于配置重载通知，支持多种方式：

<AccordionGroup>
  <Accordion icon="signal" title="Signal 通知">
    通过系统信号进行通知，适用于单机部署

    ```yaml theme={null}
    notifier:
      type: "signal"
      signal:
        signal: "SIGHUP"
        pid: "/var/run/mcp-gateway.pid"
    ```
  </Accordion>

  <Accordion icon="api" title="API 通知">
    通过HTTP API进行通知，适用于远程管理

    ```yaml theme={null}
    notifier:
      type: "api"
      api:
        port: 5235
        target_url: "http://localhost:5235/_reload"
    ```
  </Accordion>

  <Accordion icon="database" title="Redis 通知">
    通过Redis发布订阅进行通知，适用于集群部署

    ```yaml theme={null}
    notifier:
      type: "redis"
      redis:
        cluster_type: "single"
        addr: "localhost:6379"
        topic: "mcp-gateway:reload"
    ```
  </Accordion>
</AccordionGroup>

### 环境变量注入

在配置中可以使用环境变量，支持默认值：

```yaml theme={null}
# 基础语法
port: ${MCP_GATEWAY_PORT:5235}  # 使用环境变量，默认值 5235

# 字符串格式
logger:
  level: "${LOGGER_LEVEL:info}"  # 使用环境变量，默认值 info

# 服务配置中使用
config:
  ApiKey: '{{ env "API_KEY" }}'
  BaseUrl: '{{ env "API_BASE_URL" "http://localhost:8080" }}'  # 带默认值
```

### 模板函数

在请求体和响应体模板中，可以使用模板函数来处理复杂数据：

<AccordionGroup>
  <Accordion icon="function" title="toJSON">
    将对象或数组转换为 JSON 字符串，用于处理复杂数据结构

    ```yaml theme={null}
    requestBody: |-
      {
        "settings": {{ toJSON .Args.settings }},
        "notifications": {{ toJSON .Args.notifications }}
      }
    ```
  </Accordion>

  <Accordion icon="variable" title="直接使用">
    对于简单的数组和对象，可以直接使用变量

    ```yaml theme={null}
    requestBody: |-
      {
        "tags": {{.Args.tags}},
        "preferences": {{ .Args.preferences }}
      }
    ```
  </Accordion>
</AccordionGroup>

<Note>
  使用 `toJSON` 函数可以确保复杂的对象和数组被正确序列化为 JSON 格式，特别适用于嵌套结构和包含特殊字符的数据。
</Note>

### 复杂参数处理示例

以下是一个处理复杂参数的完整示例，展示了如何定义和使用 object 和 array 类型的参数：

```yaml theme={null}
args:
  - name: "settings"
    position: "body"
    required: false
    type: "object"
    description: "User custom settings as key-value pairs"
    default: "{}"
  - name: "notifications"
    position: "body"
    required: false
    type: "array"
    description: "User notification preferences"
    items:
      type: "object"
      properties:
        type:
          type: "string"
          description: "Notification type (email, push, sms)"
        channel:
          type: "string"
          description: "Notification channel (marketing, system, security)"
        enabled:
          type: "boolean"
          description: "Whether this notification is enabled"
        frequency:
          type: "number"
          description: "Notification frequency (0: realtime, 1: daily, 2: weekly, 3: monthly)"
    default: "[]"

requestBody: |-
  {
    "settings": {{ toJSON .Args.settings }},
    "notifications": {{ .Args.notifications }}
  }

responseBody: |-
  {
    "settings": {{ toJSON .Response.Data.preferences.settings }},
    "notifications": {{ toJSON .Response.Data.preferences.notifications }}
  }
```

### 文件上传处理

支持文件上传场景：

```yaml theme={null}
args:
  - name: "file"
    position: "form-data"
    required: true
    type: "string"
    description: "File to upload"
  - name: "description"
    position: "form-data"
    required: false
    type: "string"
    description: "File description"
```

## 最佳实践

<AccordionGroup>
  <Accordion icon="shield-check" title="安全性">
    * 使用环境变量存储敏感信息（如数据库密码、API密钥）
    * 在生产环境中限制CORS Origins，避免使用 "\*"
    * 启用OAuth2认证和适当的授权机制
    * 定期轮换API密钥和令牌
    * 使用加密的Redis连接存储会话数据
  </Accordion>

  <Accordion icon="zap" title="性能">
    * 合理设置超时时间和重载间隔
    * 使用Redis集群提高会话存储性能
    * 选择合适的日志级别，避免过多debug日志
    * 使用连接池减少连接开销
    * 对频繁调用的API进行缓存
    * 避免在模板中进行复杂计算
  </Accordion>

  <Accordion icon="tools" title="维护性">
    * 使用有意义的工具和服务名称
    * 添加详细的描述信息
    * 保持配置文件的整洁和可读性
    * 配置日志轮转，避免磁盘空间不足
    * 监控PID文件和进程状态
    * 设置合适的通知器类型便于配置管理
    * 定期检查和更新配置
  </Accordion>

  <Accordion icon="test-tube" title="测试">
    * 在开发环境中充分测试配置
    * 使用mock服务进行集成测试
    * 验证所有参数和响应格式
    * 测试错误处理和边界情况
  </Accordion>
</AccordionGroup>

## 配置验证

在应用配置之前，建议进行以下验证：

<Steps>
  <Step title="语法检查">
    确保YAML语法正确，无缩进错误
  </Step>

  <Step title="环境变量验证">
    检查所有必需的环境变量是否已设置
  </Step>

  <Step title="存储连接测试">
    验证数据库或Redis连接配置是否正确
  </Step>

  <Step title="引用验证">
    检查所有引用关系是否正确，如server名称匹配
  </Step>

  <Step title="模板验证">
    验证Go Template语法和变量引用
  </Step>

  <Step title="端点测试">
    确保所有endpoint都可以正常访问
  </Step>

  <Step title="权限验证">
    确保PID文件路径有写入权限
  </Step>
</Steps>

<Note>
  更多关于Go Template的使用方法，请参考[模板使用指南](/configuration/templates)。
</Note>
