
GraphQL API滲透測試指南
將其分成單獨的部分,我們可以在頂部看到代碼的控制部分:
$version: "2"
下面是實質性代碼:
namespace example.weather
/// Provides weather forecasts.
@paginated(inputToken: "nextToken", outputToken: "nextToken", pageSize: "pageSize")
service Weather {
version: "2006-03-01"
resources: [
City
]
operations: [
GetCurrentTime
]
}
resource City {
identifiers: { cityId: CityId }
properties: { coordinates: CityCoordinates }
read: GetCity
list: ListCities
resources: [
Forecast
]
}
resource Forecast {
identifiers: { cityId: CityId }
properties: { chanceOfRain: Float }
read: GetForecast
}
這里我們有服務的定義(及其分頁)以及所利用的資源以及對這些資源采取的操作。
//"pattern" is a trait.
@pattern("^[A-Za-z0-9 ]+$")
string CityId
@readonly
operation GetCity {
input := for City {
//"cityId" provides the identifier for the resource and
// has to be marked as required.
@required
$cityId
}
output := for City {
//"required" is used on output to indicate if the service
// will always provide a value for the member.
//"notProperty" indicates that top-level input member "name"
// is not bound to any resource property.
@required
@notProperty
name: String
@required
$coordinates
}
errors: [
NoSuchResource
]
}
// This structure is nested within GetCityOutput.
structure CityCoordinates {
@required
latitude: Float
@required
longitude: Float
}
//"error" is a trait that is used to specialize
// a structure as an error.
@error("client")
structure NoSuchResource {
@required
resourceType: String
}
// The paginated trait indicates that the operation may
// return truncated results.
@readonly
@paginated(items: "items")
operation ListCities {
input := {
nextToken: String
pageSize: Integer
}
output := {
nextToken: String
@required
items: CitySummaries
}
}
// CitySummaries is a list of CitySummary structures.
list CitySummaries {
member: CitySummary
}
// CitySummary contains a reference to a City.
@references([
{
resource: City
}
])
structure CitySummary {
@required
cityId: CityId
@required
name: String
}
@readonly
operation GetCurrentTime {
output := {
@required
time: Timestamp
}
}
@readonly
operation GetForecast {
input := for Forecast {
//"cityId" provides the only identifier for the resource since
// a Forecast doesn't have its own.
@required
$cityId
}
output := for Forecast {
$chanceOfRain
}
}
從這里開始,我們有一系列特征定義和嵌套結構,允許在模型內排列輸出和功能,從而更好地控制基本輸出和功能。查看此代碼,您可以看到特征定義如何解鎖功能控制。本質上,特征允許在不從根本上改變底層實體的情況下約束和格式化數據和服務。
考慮到這一點,使用像 Smithy 這樣的東西有什么優點和缺點?
對于大多數用戶來說,采用 Smithy 的最大好處是它與協議無關。并非所有開發都經過提前考慮,您今天使用的協議永遠都是正確的。采用像 Smithy 這樣的解決方案,您可以為當前的工作創建模型,這些模型可以隨著新的開發而變形、改變和改變。這為您提供了很大的靈活性,最終使您的開發擺脫了嚴格的限制。
專注于模型驅動系統可以實現機器和人類的高效可讀性。模型可以從一個系統移植到另一個系統,并轉換為其他格式和類型,從而將底層系統從外部控制的負擔中解放出來。模型也很容易比較,可以實現更好的自動化,從而提高效率。
Smithy 也是開源的,這是一個巨大的好處!與協議無關的解決方案很棒,但是當這種解決方案的開發也與源代碼控制解耦時,可能會使其關閉并集中控制,這會使其開發和迭代速度更快。 Smithy 是一個可以獨立完成很多事情的工具,但從長遠來看,將其開放給社區開發和迭代可以使其成為一些非常令人驚奇的事情的平臺!
雖然 Smithy 在其基于模型的系統上做了很多出色的工作,但它提供代碼生成作為一個重要功能。事實上,代碼生成仍然存在重大問題,即使這里提供了大量的修復和系統,這些問題也不會消失。使用 Smithy 進行代碼生成通常很有效,但與任何代碼生成工具一樣,99% 的情況下,輸出都可以,但這 1% 意味著您需要非常密切地關注并投入資源進行審查,這削弱了從代碼生成中獲得的一些好處。
Smithy 功能齊全。在某些情況下,這可能是負面的。如果您希望構建一些非常簡單的東西,只有少數人與之交互,那么為其他觀看者進行投影或為多個團隊創建模型訪問規則的想法可能不適合您。在這種情況下,讓史密斯加入的成本可能不合理。與任何事情一樣,您應該考慮 Smithy 是您需要使用的東西還是您只想使用的東西。
最后,需要簡單說明的是,這是亞馬遜開發的產品。雖然這當然不應該是采用或不采用工具的唯一原因,但該項目的長期維護和健康與亞馬遜本身的長期維護和健康息息相關。雖然亞馬遜看起來不會很快走向任何地方,但對于那些在網絡開發領域工作了很長一段時間的人來說,在其首次發布十年或二十年之后,企業發展陷入困境和崩潰的故事比比皆是,而這個肯定應該是一個考慮因素。即使產品是開源的,開源并不意味著永久開發,并且在任何特定時刻都可能會認為 Smithy 不值得花費時間或資源。
開源軟件也有轉變為更多商業許可證的趨勢。從版本 2.15 開始,Buoyant Enterprise for Linkerd 宣布 Linkerd 將不再生成開源穩定版本。截至 2024 年,Redis 有爭議地放棄了 BSD 許可證,引起社區許多人的嚴重擔憂。不幸的是,這些故事很常見,并說明了像 Smithy 這樣的解決方案的一個巨大問題——它適合開源框架,直到它不適合,而這種轉變可能會產生巨大的影響。
最終,對于采用強大的基于模型的解決方案的系統來說,Smithy 是一個不錯的選擇。雖然它對于所有實現來說可能都太重了,但它的靈活性和可擴展性使其成為許多情況下可靠的價值主張。
原文鏈接:https://nordicapis.com/overview-of-smithy-an-api-description-language-from-amazon/
GraphQL API滲透測試指南
Python + BaiduTransAPI :快速檢索千篇英文文獻(附源碼)
掌握ChatGPT API集成的方便指南
node.js + express + docker + mysql + jwt 實現用戶管理restful api
nodejs + mongodb 編寫 restful 風格博客 api
表格插件wpDataTables-將 WordPress 表與 Google Sheets API 連接
手把手教你用Python和Flask創建REST API
使用 Django 和 Django REST 框架構建 RESTful API:實現 CRUD 操作
ASP.NET Web API快速入門介紹