REST スキャフォルダー用 APIkit を使用して、RESTful API Modeling Language (RAML) または OpenAPI 仕様 (OAS) に基づいて REST API 実装のバックボーンを生成します。
API スキャフォールディング
Studio では、API をスキャフォールディングするいくつかの方法が提供されています。
-
Exchange または Maven からパブリッシュされた API をインポートする場合、ローカルファイルからインポートする場合、または Design Center からダウンロードする場合、[New Mule Project (新規 Mule プロジェクト)] ウィザードで [Scaffold Flows From These API Specifications (これらの API 仕様からフローをスキャフォールディングする)] を選択する。
-
Package Explorer で API ファイルを右クリックし、[Mule] > [Generate flows from Local REST API (ローカル REST API からフローを生成)] を選択する。
-
Package Explorer で API 連動関係を右クリックし、そのコンテキストメニューから [Generate flows (フローを生成)] を選択する。
| ローカルファイルからのスキャフォールディングは、OAS ではサポートされていません。スキャフォールディング OAS API は、Exchange でパブリッシュされたアセットでのみ使用できます。 |
実装リファレンス
REST API 仕様をスキャフォールディングする場合、APIkit では次の内容が生成されます。
-
エントリポイントとして機能するメインフローには次の内容が含まれます。
-
ソースとしての HTTP リスナー
-
メイン操作としての APIkit ルーター
APIkit ルーター は、受信した API 要求から対応する Mule フローにメッセージを送り、デフォルト値を使用してシリアル化された応答を生成するメッセージプロセッサーです。たとえば、無効な要求では、APIkit は
「bad request (不正な要求)」応答を生成し、要求された API リソース内に関連付けられたフローがない場合は「not implemented (実装されていません)」応答になります。APIkit ルーターは要求のペイロード、ヘッダー、クエリパラメーター、URI パラメーターなどの要素を検証しますが、API 仕様で指定されているすべての要素を検証するわけではありません。具体的には、ルーターは認証の適用などのセキュリティ関連の検証を実行しません。代わりに、API ゲートウェイポリシーでこの検証が行われます。この検証は、要求がルーターに到達する前に行われます。
-
Error Handler
-
-
API Console を公開する 2 つ目のフローには次のコンポーネントが含まれます。
-
ソースとしての HTTP リスナー
-
メイン操作としての APIkit コンソール
-
Error Handler
-
-
N 個のフロー (API action-resource-content-type の組み合わせごとに 1 つ) に加えて、各フローには次の内容が含まれます。
-
No source (ソースなし) (このオプションは REST および SOAP アプリケーションの APIkit でのみ使用可能です)
-
後で実際のビジネスロジックに置き換えるモック実装
-
例
<mule>
<apikit:config name="api-config" api="api.raml" outboundHeadersMapName="outboundHeaders" httpStatusVarName="httpStatus" />
<flow name="api-main">
<http:listener config-ref="HTTP_Listener_config" path="/api/*">
<http:response statusCode="#[vars.httpStatus default 200]">
<http:headers>#[vars.outboundHeaders default {}]</http:headers>
</http:response>
<http:error-response statusCode="#[vars.httpStatus default 500]">
<http:body>#[payload]</http:body>
<http:headers>#[vars.outboundHeaders default {}]</http:headers>
</http:error-response>
</http:listener>
<apikit:router config-ref="api-config" />
<error-handler>
<on-error-propagate type="APIKIT:BAD_REQUEST">
<ee:transform>
<ee:message>
<ee:set-payload><![CDATA[%dw 2.0
output application/json
---
{message: "Bad request"}]]></ee:set-payload>
</ee:message>
<ee:variables>
<ee:set-variable variableName="httpStatus">400</ee:set-variable>
</ee:variables>
</ee:transform>
</on-error-propagate>
<on-error-propagate type="APIKIT:NOT_FOUND">
<ee:transform>
<ee:message>
<ee:set-payload><![CDATA[%dw 2.0
output application/json
---
{message: "Resource not found"}]]></ee:set-payload>
</ee:message>
<ee:variables>
<ee:set-variable variableName="httpStatus">404</ee:set-variable>
</ee:variables>
</ee:transform>
</on-error-propagate>
<on-error-propagate type="APIKIT:METHOD_NOT_ALLOWED">
<ee:transform>
<ee:message>
<ee:set-payload><![CDATA[%dw 2.0
output application/json
---
{message: "Method not allowed"}]]></ee:set-payload>
</ee:message>
<ee:variables>
<ee:set-variable variableName="httpStatus">405</ee:set-variable>
</ee:variables>
</ee:transform>
</on-error-propagate>
<on-error-propagate type="APIKIT:NOT_ACCEPTABLE">
<ee:transform>
<ee:message>
<ee:set-payload><![CDATA[%dw 2.0
output application/json
---
{message: "Not acceptable"}]]></ee:set-payload>
</ee:message>
<ee:variables>
<ee:set-variable variableName="httpStatus">406</ee:set-variable>
</ee:variables>
</ee:transform>
</on-error-propagate>
<on-error-propagate type="APIKIT:UNSUPPORTED_MEDIA_TYPE">
<ee:transform>
<ee:message>
<ee:set-payload><![CDATA[%dw 2.0
output application/json
---
{message: "Unsupported media type"}]]></ee:set-payload>
</ee:message>
<ee:variables>
<ee:set-variable variableName="httpStatus">415</ee:set-variable>
</ee:variables>
</ee:transform>
</on-error-propagate>
<on-error-propagate type="APIKIT:NOT_IMPLEMENTED">
<ee:transform>
<ee:message>
<ee:set-payload><![CDATA[%dw 2.0
output application/json
---
{message: "Not Implemented"}]]></ee:set-payload>
</ee:message>
<ee:variables>
<ee:set-variable variableName="httpStatus">501</ee:set-variable>
</ee:variables>
</ee:transform>
</on-error-propagate>
</error-handler>
</flow>
<flow name="api-console">
<http:listener config-ref="HTTP_Listener_config" path="/console/*">
<http:response statusCode="#[vars.httpStatus default 200]">
<http:headers>#[vars.outboundHeaders default {}]</http:headers>
</http:response>
<http:error-response statusCode="#[vars.httpStatus default 500]">
<http:body>#[payload]</http:body>
<http:headers>#[vars.outboundHeaders default {}]</http:headers>
</http:error-response>
</http:listener>
<apikit:console config-ref="api-config" />
<error-handler>
<on-error-propagate type="APIKIT:NOT_FOUND">
<ee:transform>
<ee:message>
<ee:set-payload><![CDATA[%dw 2.0
output application/json
---
{message: "Resource not found"}]]></ee:set-payload>
</ee:message>
<ee:variables>
<ee:set-variable variableName="httpStatus">404</ee:set-variable>
</ee:variables>
</ee:transform>
</on-error-propagate>
</error-handler>
</flow>
<flow name="get:\users\userbyid:api-config">
<ee:transform>
<ee:message>
<ee:set-payload><![CDATA[%dw 2.0
output application/json
---
[
{
id: 3,
name: "Clementine Bauch",
username: "Samantha",
email: "Nathan@yesenia.net",
address: {
street: "Douglas Extension",
suite: "Suite 847",
city: "McKenziehaven",
zipcode: "59590-4157",
geo: {
lat: "-68.6102",
lng: "-47.0653"
}
},
phone: "1-463-123-4447",
website: "ramiro.info",
company: {
name: "Romaguera-Jacobson",
catchPhrase: "Face to face bifurcated interface",
bs: "e-enable strategic applications"
}
}
]]]></ee:set-payload>
</ee:message>
</ee:transform>
</flow>
<flow name="get:\users:api-config">
<ee:transform>
<ee:message>
<ee:set-payload><![CDATA[%dw 2.0
output application/json
---
[
{
id: 1,
name: "Leanne Graham",
username: "Bret",
email: "Sincere@april.biz",
address: {
street: "Kulas Light",
suite: "Apt. 556",
city: "Gwenborough",
zipcode: "92998-3874",
geo: {
lat: "-37.3159",
lng: "81.1496"
}
},
phone: "1-770-736-8031 x56442",
website: "hildegard.org",
company: {
name: "Romaguera-Crona",
catchPhrase: "Multi-layered client-server neural-net",
bs: "harness real-time e-markets"
}
}
]]]></ee:set-payload>
</ee:message>
</ee:transform>
</flow>
</mule>