我们使用机器学习技术将英文博客翻译为简体中文。您可以点击导航栏中的“中文(简体)”切换到英文版本。
介绍 Smithy CLI
Smithy 团队很高兴地宣布 S
目前,大多数开发人员使用
使用 Smithy CLI,开发人员无需任何 Java 或 Gradle 知识即可更快地使用单个命令构建模型。Smithy CLI 现在可以在 macOS、Linux 和 Windows 平台上下载。
入门
Smithy CLI 使您能够快速迭代您的 Smithy 模型。使用此工具,您可以轻松构建模型,对模型进行临时验证,比较模型的差异并对其进行查询。要在装有
$ brew tap smithy-lang/tap
$ brew install smithy-cli
有关其他平台上的安装说明或详细的安装说明,可以查看
--help 标志查看 “帮助
” 信息:
$ smithy --help
Usage: smithy [-h | --help] [--version] <command> [<args>]
Available commands:
validate Validates Smithy models.
build Builds Smithy models and creates plugin artifacts for each projection found in smithy-build.json.
diff Compares two Smithy models and reports differences.
ast Reads Smithy models in and writes out a single JSON AST model.
select Queries a model using a selector.
clean Removes Smithy build artifacts.
migrate Migrate Smithy IDL models from 1.0 to 2.0 in place.
您也可以调用附加
--help
标志的命令来查看命令特定的信息:
$ smithy build --help
Usage: smithy build [--help | -h]
[--debug] [--quiet] [--no-color]
[--force-color] [--stacktrace]
[--logging LOG_LEVEL]
[--config | -c CONFIG_PATH...]
[--no-config] [--severity SEVERITY]
[--allow-unknown-traits]
[--output OUTPUT_PATH]
[--projection PROJECTION_NAME]
[--plugin PLUGIN_NAME] [<MODELS>]
Builds Smithy models and creates plugin artifacts for each projection found in
smithy-build.json.
...
在这篇文章中,我们将在 Smithy 官方文档中的
~/weather $ tree .
.
├── model
│ ├── weather.smithy
├── smithy-build.json
建筑模型
让我们来构建我们的基本示例天气模型:
~/weather $ smithy build model/
SUCCESS: Validated 240 shapes
Validated model, now starting projections...
── source ────────────────────────────────────────────────────────────────────
Completed projection source (240): weather/build/smithy/source
Summary: Smithy built 1 projection(s), 3 plugin(s), and 4 artifacts
查看构建工件(
恶劣天气/构建/smithy/source ),我们会根据我们的构建配置(smithy-build
.json)找到几个文件:
~/weather $ tree .
.
├── build
│ └── smithy
│ └── source
│ ├── build-info
│ │ └── smithy-build-info.json -- build metadata (projections, validation, ...)
│ ├── model
│ │ └── model.json -- JSON AST
│ └── sources
│ ├── manifest -- an inventory of the build's smithy models
│ └── weather.smithy -- a copy of our example weather model
├── model
│ └── weather.smithy
└── smithy-build.json
在这种情况下,我们的 sm
ithy-build.json 中没有配置除默认值之外的构建
行为 ,因此构建示例天气模型仅呈现模型的 JSON AST。有关配置编译和编译工件的更多详细信息,请查看 s
整理和验证模型
诸如
我们可以使用
// --- model/weather.smithy ---
$version: "2"
metadata validators = [{
name: "EmitEachSelector"
id: "OperationMissingDocumentation"
message: "This operation is missing documentation"
namespaces: ["example.weather"]
configuration: {
selector: """
operation:not([trait|documentation])
"""
}
}]
namespace example.weather
...
然后,我们将使用 validate 命令对天气模型运行
验证
:
~/weather $ smithy validate model/
── DANGER ────────────────────────────────────── OperationMissingDocumentation
Shape: example.weather#GetCity
File: model/weather.smithy:46:1
45| @readonly
46| operation GetCity {
| ^
This operation is missing documentation
── DANGER ────────────────────────────────────── OperationMissingDocumentation
Shape: example.weather#ListCities
File: model/weather.smithy:92:1
88| // The paginated trait indicates that the operation may
89| // return truncated results.
90| @readonly
91| @paginated(items: "items")
92| operation ListCities {
| ^
This operation is missing documentation
...
FAILURE: Validated 240 shapes (DANGER: 4)
有了这样定义自定义验证规则的能力,您可以为 Smithy 模型强制执行通用标准,并确保最佳实践得到遵守。有关在 Smithy 中进行验证的更多信息,请查看
差异模型
如果我们对模型进行更改,我们将使用 smithy
diff
命令检查是否存在向后兼容性问题。
让我们修改示例模型中
首先,复制模型并重命名复制的模型(we
getCurrentTimeOut
put 形状中的时间 成员。
ather-old.smith
y):
$ cp model/weather.smithy weather-old.smithy
现在,更改 “新” 模型文件中的形状:
// --- model/weather.smithy ---
...
@output
structure GetCurrentTimeOutput {
@required
time: String
}
...
现在,让我们针对此更改进行兼容性检查:
~/weather $ smithy diff --old weather-old.smithy --new model/weather.smithy
── DIFF ERROR ─────────────────────────────────────────── ChangedMemberTarget
Shape: example.weather#GetCurrentTimeOutput$time
File: model/weather.smithy:138:5
136| structure GetCurrentTimeOutput {
···|
138| time: String
| ^
The shape targeted by the member example.weather#GetCurrentTimeOutput$time
changed from smithy.api#Timestamp (timestamp) to smithy.api#String (string).
The type of the targeted shape changed from timestamp to string.
FAILURE: Validated 240 shapes (ERROR: 1)
我们通过更改已经有先前定义的形状的数据类型做出了重大更改(
错误
)。这很危险,因为模型版本之间的向后兼容性中断。使用您的旧模型的客户端将无法再安全地调用
getCurrentTim
e 操作。有关安全改进模型的更多信息,请参阅
查询模型
要查询天气模型中的所有形状,我们可以使用以下语句:
~/weather $ smithy select --selector '[id|namespace = "example.weather"]' model/
example.weather#City
example.weather#CityCoordinates
example.weather#CityCoordinates$latitude
example.weather#CityCoordinates$longitude
...
example.weather#Weather
如果你想在我们的模型中找到所有未记录的操作怎么办?我们可以使用以下语句来回答这个问题:
~/weather $ smithy select --selector 'operation:not([trait|documentation])' model/
example.weather#GetCity
example.weather#GetCurrentTime
example.weather#GetForecast
example.weather#ListCities
您可以根据需要对这个过程进行迭代,以回答有关模型的问题,一旦有了选择器,就可以在验证中使用它了。要更深入地了解 Smithy 选择器,请通读
自定义构建
构建过程最强大的功能之一是可扩展性。你可以使用 s
mithy-build.json 文件自定义构建
,根据需要添加投影或插件。让我们使用 Smithy CLI 在 TypeScript 中生成客户端,将其配置为使用
让我们创建一个新的、更简单的服务模型用于演示目的。我们的工作空间应具有以下结构:
我们的新模型文件
time.smithy
应该包含以下代码:
// --- model/time.smithy ---
$version: "2"
namespace example.time
service Time {
version: "0.0.1"
operations: [GetCurrentTime]
}
/// An operation for getting the current time
@readonly
@http(code: 200, method: "GET", uri: "/time",)
operation GetCurrentTime {
output := {
@required
@timestampFormat("date-time")
time: Timestamp
}
}
要为时间服务生成打字稿客户端,我们的构建配置文件应包含 TypeScript 插件和用于生成时间模型代码的参数:
// --- smithy-build.json ---
{
"version": "1.0",
"projections": {
"source": {
"plugins": {
"typescript-codegen": {
"service": "example.time#Time",
"package": "@example/time",
"packageVersion": "0.0.1"
}
}
}
},
"maven": {
"dependencies": [
"software.amazon.smithy:smithy-model:1.30.0",
"software.amazon.smithy.typescript:smithy-typescript-codegen:0.14.0"
]
}
}
该版本将应用打字稿代码生成器插件来生成代码,并将解析来自Maven的生成器的依赖关系,如配置中的mav
en
部分所示。让我们构建模型并生成代码:
~/time $ smithy build model/
SUCCESS: Validated 378 shapes
Validated model, now starting projections...
[WARNING] Unable to find a protocol generator for example.time#Time: Unable to derive the protocol setting of the service `example.time#Time`
because no protocol definition traits were present. You need to set an explicit `protocol` to generate in smithy-build.json to generate this service.
── source ────────────────────────────────────────────────────────────────────
Completed projection source (378): time/build/smithy/source
Summary: Smithy built 1 projection(s), 4 plugin(s), and 22 artifacts
在工作
区的 build/smithy/source/typescript-codegen 目录下为时间客户端生成了多个 TypeScript 源
文件和配置文件。因为我们的
时间
服务没有指定协议,所以打印了警告,但出于演示目的,我们可以放心地将其忽略。让我们来看看 bu
ild/Smithy/Source/Typescript-Codegen/src/
Time.ts 文件中生成的代码片段:
// smithy-typescript generated code
import { TimeClient } from "./TimeClient";
import {
GetCurrentTimeCommand,
GetCurrentTimeCommandInput,
GetCurrentTimeCommandOutput,
} from "./commands/GetCurrentTimeCommand";
import { HttpHandlerOptions as __HttpHandlerOptions } from "@aws-sdk/types";
export class Time extends TimeClient {
/**
* An operation for getting the current time
*/
public getCurrentTime(
args: GetCurrentTimeCommandInput,
options?: __HttpHandlerOptions,
): Promise<GetCurrentTimeCommandOutput>;
public getCurrentTime(
args: GetCurrentTimeCommandInput,
cb: (err: any, data?: GetCurrentTimeCommandOutput) => void
): void;
public getCurrentTime(
args: GetCurrentTimeCommandInput,
options: __HttpHandlerOptions,
cb: (err: any, data?: GetCurrentTimeCommandOutput) => void
): void;
public getCurrentTime(
args: GetCurrentTimeCommandInput,
optionsOrCb?: __HttpHandlerOptions | ((err: any, data?: GetCurrentTimeCommandOutput) => void),
cb?: (err: any, data?: GetCurrentTimeCommandOutput) => void
): Promise<GetCurrentTimeCommandOutput> | void {
const command = new GetCurrentTimeCommand(args);
if (typeof optionsOrCb === "function") {
this.send(command, optionsOrCb)
} else if (typeof cb === "function") {
if (typeof optionsOrCb !== "object")
throw new Error(`Expect http options but get ${typeof optionsOrCb}`)
this.send(command, optionsOrCb || {}, cb)
} else {
return this.send(command, optionsOrCb);
}
}
}
从前面的代码片段中,我们可以观察到代码生成器中使用模型中的
getCurrentTime 操作在时间
服务的 TypeScript 客户端中创建了一个名为
getCurrentTim
e 的方法。如果这是一项真正的服务,则客户可以使用此方法在他们自己的 TypeScript 包中向我们的服务提出请求。仅使用 Smithy CLI,我们就能够构建我们的简单时间模型,并在 TypeScript 中生成一些基本的客户端代码——要做到这一点,你需要使用 Gradle 并熟悉 Gradle 生态系统来管理你的项目。
下一步是什么?
立即开始使用 Smithy CLI 来简化使用 Smithy 构建模型时的体验。Smithy CLI 使您可以轻松构建、验证和快速迭代您的模型。
我们将不断改进 CLI 以增强开发者体验,因此,请发表评论或在
作者简介:
*前述特定亚马逊云科技生成式人工智能相关的服务仅在亚马逊云科技海外区域可用,亚马逊云科技中国仅为帮助您发展海外业务和/或了解行业前沿技术选择推荐该服务。