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

# Client

> rest 包是 Go SDK 的入口点。通过一个 API 密钥实例化客户端，并通过单一接口访问每一个资源 —— 应用、数据库、workspace、用户和平台服务。

## 要求

* **Go 1.24** 或更新版本
* **零外部依赖** —— SDK 仅基于 Go 标准库构建
* 一个有效的 API 密钥 —— 可在 [Square Cloud 控制台](https://squarecloud.app/zh/dashboard)的 **My Account → Regenerate API/CLI KEY** 中申请

## 安装

```bash theme={null}
go get github.com/squarecloudofc/sdk-api-go/v2
```

该模块提供两个包：

| 包             | 导入路径                                                  | 内容                          |
| ------------- | ----------------------------------------------------- | --------------------------- |
| `rest`        | `github.com/squarecloudofc/sdk-api-go/v2/rest`        | HTTP 客户端、资源接口、请求选项、错误、SSE 流 |
| `squarecloud` | `github.com/squarecloudofc/sdk-api-go/v2/squarecloud` | 所有请求/响应类型和结构体               |

## 实例化客户端

```go theme={null}
package main

import (
	"fmt"
	"os"

	"github.com/squarecloudofc/sdk-api-go/v2/rest"
)

func main() {
	client := rest.NewClient(os.Getenv("SQUARECLOUD_API_KEY"))
	defer client.Close()

	api := rest.New(client)

	user, err := api.SelfUser()
	if err != nil {
		panic(err)
	}
	fmt.Println(user.Name)
}
```

`rest.NewClient(token, opts...)` 构建底层 HTTP 客户端；`rest.New(client)` 将其包装为 `rest.Rest`，即暴露所有资源的接口。始终 `defer client.Close()` 以释放空闲连接。

### 客户端配置（`ConfigOpt`）

`rest.NewClient` 在 token 之后接受可选的 `ConfigOpt`：

| 选项                                  | 默认值                              | 说明                            |
| ----------------------------------- | -------------------------------- | ----------------------------- |
| `rest.WithLogger(*slog.Logger)`     | 丢弃日志                             | 用于请求/响应调试的结构化日志器              |
| `rest.WithHTTPClient(*http.Client)` | 30s 超时                           | 自定义 `*http.Client`（代理、传输层、超时） |
| `rest.WithURL(string)`              | `https://api.squarecloud.app/v2` | API 基础 URL                    |
| `rest.WithUserAgent(string)`        | SDK 默认值                          | 自定义 `User-Agent` 请求头          |

```go theme={null}
client := rest.NewClient(
	os.Getenv("SQUARECLOUD_API_KEY"),
	rest.WithLogger(slog.Default()),
	rest.WithHTTPClient(&http.Client{Timeout: 10 * time.Second}),
)
```

## 模块

`rest.Rest` 按资源领域内嵌了一个接口，外加本页记录的用户和服务方法：

| 接口             | 覆盖范围                             | 文档                                       |
| -------------- | -------------------------------- | ---------------------------------------- |
| `Applications` | 管理、上传、文件、环境变量、snapshot、部署、网络、实时流 | [管理应用](/zh/sdks/go/managing_application) |
| `Databases`    | 创建、管理、凭据和 snapshot               | [数据库](/zh/sdks/go/databases)             |
| `Workspaces`   | 创建、成员、共享应用                       | [Workspaces](/zh/sdks/go/workspaces)     |

## 获取已认证用户

`api.SelfUser()` 返回一个包含账户详情和当前套餐的 `squarecloud.User`。

```go theme={null}
user, err := api.SelfUser()
if err != nil {
	panic(err)
}

fmt.Println(user.ID)       // "abcdef0123456789abcdef01"
fmt.Println(user.Name)     // "John Doe"
fmt.Println(user.Email)    // "john@example.com"
fmt.Println(user.Locale)   // "en-US"
fmt.Println(user.Plan.Name)             // e.g. "standard"
fmt.Println(user.Plan.Duration)         // plan duration, e.g. "monthly"
fmt.Println(user.Plan.Memory.Limit)     // MB
fmt.Println(user.Plan.Memory.Available) // MB
fmt.Println(user.Plan.Memory.Used)      // MB
fmt.Println(user.CreatedAt)
```

| 字段          | 类型                     | 说明                                                      |
| ----------- | ---------------------- | ------------------------------------------------------- |
| `ID`        | `string`               | 用户 ID（24 位十六进制字符）                                       |
| `Name`      | `string`               | 显示名称                                                    |
| `Email`     | `string`               | 账户邮箱                                                    |
| `Locale`    | `string`               | 首选语言环境，例如 `"en-US"`                                     |
| `Plan`      | `squarecloud.UserPlan` | `Name`、`Memory{Limit, Available, Used}`（MB）和 `Duration` |
| `CreatedAt` | `string`               | 账户创建日期                                                  |

## 列出你的应用和数据库

`api.GetApplications()` 和 `api.GetDatabases()` 通过 `/users/me` endpoint 列出你拥有的一切，返回精简的 `squarecloud.UserApplication` / `squarecloud.UserDatabase` 描述符：

```go theme={null}
apps, err := api.GetApplications()
if err != nil {
	panic(err)
}
for _, app := range apps {
	fmt.Printf("%s (%s) — %dMB\n", app.Name, app.ID, app.RAM)
}

dbs, err := api.GetDatabases()
if err != nil {
	panic(err)
}
for _, db := range dbs {
	fmt.Printf("%s (%s)\n", db.Name, db.ID)
}
```

要获取单个资源的完整记录，请使用 `GetApplication` / `GetDatabase` —— 参见[管理应用](/zh/sdks/go/managing_application)和[数据库](/zh/sdks/go/databases)。

## 列出 snapshot 历史（账户级）

`api.UserSnapshots(scope)` 返回你在给定领域拥有的所有 snapshot：

```go theme={null}
appSnapshots, err := api.UserSnapshots(squarecloud.SnapshotScopeApplications)
if err != nil {
	panic(err)
}

dbSnapshots, err := api.UserSnapshots(squarecloud.SnapshotScopeDatabases)
if err != nil {
	panic(err)
}
```

关于 snapshot 载荷的详情，请参阅 [Snapshots](/zh/sdks/go/snapshots)。

## 平台状态

`api.ServiceStatus()` 暴露聚合后的平台健康状况（与公开状态页展示的数据相同）。

```go theme={null}
status, err := api.ServiceStatus()
if err != nil {
	panic(err)
}

fmt.Println(status.Status)  // "ok" | "degraded" | "down"
fmt.Println(status.Message) // human-readable summary
```

<Note>
  与大多数 v2 endpoint 不同，此路由**不会**将其载荷包裹在标准的 `{ status, code, response }` 信封中 —— 它直接以 `{ status, message }` 响应。
</Note>

## 请求选项

每个方法都接受末尾的 `...rest.RequestOpt`，用于自定义单个请求：

| 选项                                | 说明                                 |
| --------------------------------- | ---------------------------------- |
| `rest.WithContext(ctx)`           | 附加一个 `context.Context`，用于取消或设置截止时间 |
| `rest.WithQueryParam(key, value)` | 追加一个查询参数                           |
| `rest.WithHeader(key, value)`     | 设置一个请求头                            |
| `rest.WithToken(token)`           | 仅为本次请求覆盖认证 token                   |

```go theme={null}
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
defer cancel()

user, err := api.SelfUser(rest.WithContext(ctx))
if err != nil {
	panic(err)
}
```

## 错误处理

任何非 2xx 响应都会以 `*rest.APIError` 返回，暴露 `StatusCode`、`Code` 和 `Message`。使用惯用的 `errors.As` 解包：

```go theme={null}
app, err := api.GetApplication("invalid-id")
if err != nil {
	var apiErr *rest.APIError
	if errors.As(err, &apiErr) {
		fmt.Println(apiErr.StatusCode) // e.g. 404
		fmt.Println(apiErr.Code)       // e.g. "APP_NOT_FOUND"
		fmt.Println(apiErr.Message)
	}
	return
}
```

两个辅助函数简化了常见检查：

* `rest.ErrorCode(err) string` —— 返回 API 错误代码（当错误不是 `*rest.APIError` 时返回 `""`）
* `rest.IsRateLimit(err) bool` —— 报告该错误是否属于任一速率限制代码（`KEEP_CALM`、`RATE_LIMIT`、`RATE_LIMIT_EXCEEDED`、`RATELIMIT`、`DELAY_NOW`）

```go theme={null}
if err != nil {
	if rest.IsRateLimit(err) {
		time.Sleep(5 * time.Second)
		// retry...
	}

	switch rest.ErrorCode(err) {
	case "APP_NOT_FOUND":
		fmt.Println("application does not exist")
	case "ACCESS_DENIED":
		fmt.Println("invalid API key")
	}
}
```

这些错误代码与 `@squarecloud/api-types` 使用的相同 —— 参见 [JS SDK 参考中的完整代码表](/zh/sdks/js/client)。
