跳到正文

快速开始:5 分钟完成第一次调用

查看 Markdown

本教程帮助你在 5 分钟内完成平台接口的第一次调用。

注册开发者账号

在浏览器中打开开发者门户 https://dev.${DOMAIN}。开发者组织有两种来法:

  • 自助注册:在门户的注册页填组织名称、你的名字和邮箱。平台给你建好开发者组织,你是它的管理员,激活码发到这个邮箱。部署不能发邮件时自助注册是关闭的,返回 HTTP 503(self sign-up is closed on this deployment),这时请平台运营为你开通。
  • 由平台运营开通:运营建好开发者组织,把你的邮箱设为第一位成员(开发者兼管理员)。激活码发到你的邮箱,或者由运营交给你。

第一次登录:在门户点「登录」,转到平台的登录页,填登录名(邮箱),用激活码设置密码。平台自己的登录页上这一步是「输入激活码 / 验证码,设置密码」;部署用身份服务自己的登录页时,这一页的标题是「E-Mail Verification」,在验证码(Code)一栏填激活码,再填新密码。之后每次登录填登录名和密码。登录页可能请你设置双因素认证(「2-Factor Setup」);组织没有强制要求时可以跳过,以后再设。登录后回到门户。

组织管理员在门户的「团队」页邀请成员、调整角色:「开发者」可以建应用、传版本、提交审核;「管理员」另外能管理团队和 API 凭证。脚本和命令行不走浏览器登录,而用 API 凭证,见 认证与凭证 的「调用开发者平台接口」。

创建一个应用

登录开发者门户,点「新建应用」,在「创建上架条目」对话框里选类型(应用、模板等),填名称和 ID。命令行里用接口建,或者第一次 k3 publish 时自动建:

终端
k3 api POST /api/dev/apps --data '{"id": "my-app", "listing": {"name": "我的应用"}}'

应用 ID 在整个平台唯一:3 到 48 个小写字母、数字和 -,以字母开头,不能是平台保留的词。已被别的组织占用时创建返回 HTTP 409;ID 格式正确但被保留时也返回 HTTP 409,错误码 app_id_reserved,说明里写明这个 ID 是保留的(之前的平台版本对保留的 ID 返回 HTTP 422 validation_failed)。distribution 这样的目录应用 ID 由平台保留,要接手维护由平台运营转交,见 本地开发与测试企业 的「接手目录里的应用」;转交之前怎样跑这类应用的代码,见同一页的「转交之前运行目录应用的代码」。

分发方式不在创建时选,由你的开发者组织决定:

  • 商店应用:独立的开发者组织(自助注册或由运营开通)建的应用。发布到应用市场,供多个企业安装,版本要经平台审核;上架之前要完成门户里的企业认证,测试不需要。
  • 自建应用:属于某个企业的开发者组织建的,只在这个企业里用。版本提交后自动通过,不审核。这样的组织只建集成,而且在工作台的「我的组织 → 开放平台」里建,不在开发者门户。

由谁运行应用也不在创建时选,而由每个版本的清单决定:写了 runtime.image 的版本由平台托管运行;没写的由你自己运行,平台按清单的 opsApi 与 web.url 找它(见 本地开发与测试企业 的「开发版本的 opsApi 与 web.url」)。所以创建的回答里 hosting 总是 external,它不是一个可选的字段。

建测试企业并以测试员工身份使用

测试企业是你的组织自己的租户,数据独立、不计费,可以带示例客户、多维表和测试员工,开发调试都在这里。在门户的「测试企业」页点「新建测试企业」,或者用命令行:

终端
k3 test-enterprise create "我的测试企业" --email sbx-admin@example.com --sample general

--email 是测试企业的管理员,要一个平台上还没有账号的邮箱:你自己登录门户的邮箱会被拒绝(HTTP 422 already in use)。回答里的测试企业 ID 就是下文的 TENANT。接着:

  1. 把应用的一个版本装进去:门户应用详情的「测试企业」页签点「试装」,草稿也可以装。
  2. 以测试员工身份进入:每个测试企业有测试店长、测试前台、测试员工三个人。k3 test-enterprise users <测试企业 ID> 列出他们,k3 test-enterprise signin <测试企业 ID> <员工 ID> 打开一个一次性的登录地址,进到测试企业的工作台,像企业的员工一样使用应用。门户里每个测试员工旁边也有「以此身份打开」。

数量、期限、试装的规则和命令行的全部用法见 本地开发与测试企业。

获取测试密钥

进入应用的凭证管理页面。

创建一个环境为 test 的应用密钥(命令行:k3 credentials create <应用 ID> --env test),获取你的客户端 ID(client_id)与客户端密钥(client_secret)。测试环境密钥以 kwo_test_ 为前缀。

客户端密钥仅在创建时完整展示一次。请将它妥善保存在环境变量中:

终端
export CLIENT_ID="${CLIENT_ID}"
export CLIENT_SECRET="${CLIENT_SECRET}"
export TENANT="${TENANT}"
export DOMAIN="${DOMAIN}"

换取访问令牌

调用令牌端点 POST https://api.${DOMAIN}/open/v1/oauth/token 换取令牌。认证信息可以通过 HTTP Basic 认证头提供,也可以写在请求正文中。

使用 curl 发起请求:

终端
curl -sS -X POST "https://api.${DOMAIN}/open/v1/oauth/token" \
  -u "${CLIENT_ID}:${CLIENT_SECRET}" \
  -H "Content-Type: application/x-www-form-urlencoded" \
  -d "grant_type=client_credentials&tenant=${TENANT}"

请求成功返回 HTTP 200,正文包含有效期为 300 秒的 Bearer 访问令牌:

{
  "access_token": "at_test_example_token_value",
  "token_type": "Bearer",
  "expires_in": 300,
  "scope": "platform:ping",
  "tenant": "test_corp",
  "environment": "test"
}

将返回的令牌存入环境变量:

终端
export ACCESS_TOKEN="at_test_example_token_value"

调用 whoami 接口

持有访问令牌后,向 GET https://api.${DOMAIN}/open/v1/whoami 发送请求以验证身份:

终端
curl -sS -X GET "https://api.${DOMAIN}/open/v1/whoami" \
  -H "Authorization: Bearer ${ACCESS_TOKEN}"

接口返回当前令牌关联的租户、应用、凭证与权限范围:

{
  "tenant": "test_corp",
  "app": "app_example_id",
  "credential": "crd_example_id",
  "scopes": ["platform:ping"]
}

使用 Go SDK 调用

Go SDK 负责自动获取令牌、在到期前 60 秒自动刷新、处理重试与游标分页。

安装 SDK:

终端
go get github.com/21stware/raise-go

raise-go 发布在公共的 Go 模块代理上。连不上公共代理时,平台在 https://dev.${DOMAIN}/dl/go 也提供一个只读的模块代理,但它只有这个平台构建时带的那个 raise-go 版本,通常是最新版;别的版本答 404,go 命令接着试 GOPROXY 里的下一个:

终端
export GOPROXY="https://dev.${DOMAIN}/dl/go,https://proxy.golang.org,direct"

只能用平台的代理时,项目要用它提供的那个版本(k3 sdk update 升到最新版)。

编写并运行以下代码:

package main

import (
	"context"
	"fmt"
	"log"
	"os"

	"github.com/21stware/raise-go"
)

func main() {
	c := raise.New(os.Getenv("CLIENT_ID"), os.Getenv("CLIENT_SECRET"),
		raise.WithTenant(os.Getenv("TENANT")),
		raise.WithBaseURL("https://api."+os.Getenv("DOMAIN")+"/open/v1"),
	)
	me, err := c.Platform.Whoami(context.Background())
	if err != nil {
		log.Fatal(err) // *raise.Error:err.Code、err.RequestID
	}
	fmt.Println(me.Tenant, me.App, me.Scopes)
}

使用 TypeScript SDK 调用

TypeScript SDK 支持 Node.js 18+ 与现代边缘运行时,提供零外部依赖的客户端实现。

安装 SDK:

终端
npm install "https://dev.${DOMAIN}/dl/sdk/21stware-raise-sdk-0.7.7.tgz"

npm 包不在公共的 npm 注册表上,从平台的 /dl/sdk/ 安装,不用登录(应用 SDK 与套件包见下面的「安装应用 SDK 与套件包」)。GET https://dev.${DOMAIN}/dl/sdk/ 以 JSON 列出平台提供的 SDK 与套件包(文件名里带版本号),把上面的文件名换成列表里的那个。

编写并运行以下代码:

import { Raise } from '@21stware/raise-sdk'

const raise = new Raise({
  clientId: process.env.CLIENT_ID!,
  clientSecret: process.env.CLIENT_SECRET!,
  tenant: process.env.TENANT,
  baseUrl: `https://api.${process.env.DOMAIN}/open/v1`,
})

const me = await raise.platform.whoami()
console.log(me.tenant, me.app, me.scopes)

用模板创建一个应用

命令行工具 k3 可以生成一个完整的应用项目:Go 服务端、React 页面和清单 manifest.json。项目依赖公开发布的 Go SDK github.com/21stware/raise-go(v0.7.7),构建时从 Go 模块代理下载,项目里不带 SDK 的副本,go.mod 也没有 replace。

终端
k3 app init my-app --module example.com/my-app
cd my-app
go build ./...

服务端用 SDK 的应用工具包 appkit 写(api/app)。appkit.Serve 是整个应用:调用者来自宿主网关转来的页面令牌(K3-App-Token),用宿主的公钥核验,请求里自带的身份头一律不认;人员、权限、审计经 appkit.Client 调宿主的 /app/v1;助理的草稿经 appkit.MountDrafts;op 只接受宿主签名的断言。进程只读宿主规范规定的应用环境:K3_PLATFORM_URL、K3_APP_CLIENT_ID、K3_APP_CLIENT_SECRET,以及 PORT 和 K3_BASE_DOMAIN。所以同一个程序既能由平台托管运行,也能放在别的宿主后面运行,例如参考宿主(见 脱离平台运行)。在本机接测试企业的做法见 本地开发与测试企业 的「平台根地址:RAISE_BASE_URL 与 K3_PLATFORM_URL」。

清单由代码生成:改了 api/app/app.go 里的清单之后,运行 go run ./api manifest > manifest.json。页面在 web/,用 @21stware/raise-app-kit 0.4.1 的 bootstrap,构建到 api/app/webdist,由服务端在 / 提供。0.4.1 的页面只能在工作台里打开;脱离平台打开页面、按宿主的能力隐藏入口,要等 @21stware/raise-app-kit 0.5 发布。

模板把数据放在内存里。应用有自己的数据时,版本在清单里用 data.migrations 声明自己的表结构,用 runtime.image 声明服务端镜像(按摘要固定),由平台托管运行,平台为它准备专属的数据库。带 data.migrations 的版本只能托管运行,数据库连接只交给平台运行的进程。在平台之外运行的应用拿不到平台的数据库,数据放在应用自己的存储里。开发时怎样在测试企业里跑这样的应用,见 本地开发与测试企业 的「有自己数据的应用」。

模板固定的是 v0.7.7,即目前最新发布的版本。以后的版本发布后,升级到 SDK 的最新版本:

终端
k3 sdk update

它在项目目录里依次运行 go get github.com/21stware/raise-go@latest 和 go mod tidy。

安装应用 SDK 与套件包

应用的 React 页面用应用 SDK @21stware/raise-app-sdk 与套件包 @21stware/raise-app-kit。它们和服务端 SDK 一样从平台的 /dl/sdk/ 安装,不用登录,也不用令牌。/dl/sdk/ 保留每个已发布的版本,钉在旧版本上的项目也能从这里安装。

每个包写明了它依赖的其他 @21stware/* 包的确切版本,这些包要一起装:

  • @21stware/raise-app-kit 依赖 @21stware/raise-design、@21stware/raise-platform、@21stware/raise-app-sdk;
  • @21stware/raise-app-sdk 依赖 @21stware/raise-bridge。

先把 tarball 下载到项目里,再从文件安装。直接 npm install https://…/x.tgz 装不上:npm 会去公共注册表找这些依赖,那里没有。下面是 SDK 0.7.7 发布的版本:

终端
mkdir -p vendor
for f in 21stware-raise-app-kit-0.4.1.tgz 21stware-raise-app-sdk-1.2.0.tgz \
         21stware-raise-design-0.2.3.tgz 21stware-raise-platform-0.2.2.tgz 21stware-raise-bridge-1.1.0.tgz; do
  curl -fsSL -o "vendor/$f" "https://dev.${DOMAIN}/dl/sdk/$f"
done
npm install ./vendor/*.tgz

GET https://dev.${DOMAIN}/dl/sdk/ 答一个 JSON:{"npm": […], "go": […]}。npm 的每项是一个 tarball,有 name、version、file、size、sha256 和 url;go 的每项是平台的 Go 模块代理(/dl/go/)里的一个 module 和 version。部署没有带这些包时答 HTTP 404。版本不同时按列表换文件名。

/dl/sdk/ 上的 npm 包和 /dl/go/ 上的 raise-go 都保留发布过的每个版本。在这之前构建的部署,旧的 npm 版本会得到 404:按列表换成现在的版本,或者用提交在仓库里的 vendor/。每个版本同时发布哪些套件版本,见 App API 的「兼容矩阵」。react 等其他依赖仍从公共 npm 注册表安装。

把 vendor/ 提交到应用的仓库,CI 和别的机器就不必访问平台。

这些包没有发布到 npmjs.org,也没有发布到 GitHub Packages(npm.pkg.github.com)。

下一步

本页目录