投稿者

インターシステムズジャパン
記事 Toshihiko Minamoto · 9月 28, 2023 22m read

OpenAPI Suite - パート 1

コミュニティの皆さん、こんにちは。

私が作成した OpenAPI-Suite という最新のパッケージをご紹介します。これは、OpenAPI 仕様バージョン 3.0 から ObjectScript コードを生成するツールセットです。  簡単に言うと、これらのパッケージでは以下を行うことができます。

  • サーバーサイドクラスの生成。  ^%REST による生成コードに非常に似ていますが、バージョン 3.0 がサポートされていることに付加価値があります。
  • HTTP クライアントクラスの生成。
  • クライアントプロダクション(ビジネスサービス、ビジネスオペレーション、ビジネスプロセス、Ens.Request、Ens.Response)クラスの生成。
  • コードの生成とダウンロードまたはサーバーでの直接コンパイルを行う Web インターフェース。
  • バージョン 1.x からバージョン 3.0 への仕様の変換。
  • 概要

    OpenAPI Suite は多数のパッケージに分割されており、様々な開発者コミュニティライブラリや公開 REST サービスを使用しています。  以下の図では、開発されたすべてのパッケージと、使用されているライブラリと Web サービスを示しています。

    注意: 公開 REST サービスの使用に問題がある場合は、コンバーターとバリデーターサービスの Docker インスタンスを開始することができます。

    各パッケージの機能

    OpenAPI Suite は、メンテナンス、改善、および今後の拡張を行いやすくするために、様々なパッケージで設計されています。  パッケージごとに役割がありますので、  それを確認してみましょう!

    openapi-common-lib

    これには、他のパッケージのすべての共通コードが含まれています。  たとえば、openapi-client-genopenapi-server-gen は、OpenAPI 仕様の以下の入力を受け入れます。 

  • URL
  • ファイルパス
  • %Stream.Object 
  • %DynamicObject
  • YAML 形式
  • JSON 形式
  • OpenAPI バージョン 1.x、2.x、3.0.x
  • ただし、%DynamicObject 内の仕様 3.0.x のみを処理できます。  変換のコードはこのパッケージにあります。  また様々なユーティリティも含まれています。  

    swagger-converter-cli

    openapi-common-lib の依存関係です。  これは、OpenAPI バージョン 3.0 でバージョン 1.x または 2.x を変換するために公開 REST サービスの converter.swagger.io を使用する HTTP クライアントです。

    swagger-validator-cli

    これも openapi-common-lib の依存関係です。名前は「validator」となっていますが、仕様の検証に使用されるものではありません。  converter.swagger.io は、OpenAPI 仕様の構造を単純化できるように、「parse」サービスを提供しています。  例: 「nested object definition」の定義を作成し、それを「$ref」に置換します。  これにより、コード生成アルゴリズムで処理されるケース数が軽減されます。

    openapi-client-gen

    このパッケージは、開発者が REST サービスを使用しやすくするクライアントサイドのコード生成専用です。

    単純な HTTP クライアントまたはプロダクションクライアント(ビジネスサービス、プロセス、オペレーション、プロダクションクラス)が含まれます。  元々、OpenAPI 2.x をサポートするために作成されていましたが、バージョン 3.x をサポートするように完全にリファクタリングされました。

    openapi-server-gen

    これは openapi-client-gen とは逆に、サーバーサイドのコード生成専用です。  ^%REST が存在するため、仕様バージョン 2.0 ではなく、バージョン 3.0 サポートがこのパッケージのターゲットとなっています。  

    openapi-suite

    上記すべてのパッケージをひとまとめにし、以下を行う REST API を提供します。 

  • コードを生成し、IRIS インスタンスでコードをコンパイルします。
  • コンパイルせずにダウンロードのみのコードを生成します。
  • この REST API を使用し、OpenAPI Suite の機能を使用するための Web インターフェースも提供されています。

    ライブラリ

    以下に、この開発で利用した DC 上の既存のライブラリをいくつか紹介します。

    objectscript-openapi-definition

    OpenAPI 仕様からモデルクラスを生成する便利なライブラリです。  これはこのプロジェクトで非常に重要な要素であり、私自身も貢献しているライブラリです。

    ssl-client

    SSL 構成を作成できるようにします。  主に、HTTPS リクエストの「DefaultSSL」という名前の構成の作成に使用されています。  

    yaml-utils

    YAML 形式仕様の場合に、このライブラリは JSON 形式に変換するために使用されます。  このプロジェクトでは不可欠なライブラリです。  ちなみに、最初は openapi-client-gen バージョン 1 で YAML 仕様をテストするために開発されました。

    io-redirect

    これは私のライブラリの 1 つです。「write」をストリーム、ファイル、グローバル、または文字列変数にリダイレクトできます。  ログのトレースを維持するために、REST サービスで使用されています。  このコミュニティ記事からアイデアを得ました。

    IPM によるインストール

    このスイートをインストールするには、IPM(zpm)の使用が最適です。  多数のパッケージと依存関係があるため、IPM を使用するのが確実に便利と言えます。

    zpm "install openapi-suite"; optional; zpm "install swagger-ui"

     

    Docker によるインストール

    特別なことは何もありません。このプロジェクトは intersystems-iris-dev-template を使用しています。

    git clone git@github.com:lscalese/openapi-suite.git
    cd openapi-suite
    docker-compose up -d

    Iris の起動にエラーがある場合は、おそらく iris-main.log の権限の問題と思われます。

    以下を試してみてください。

    touch iris-main.log && chmod 777 iris-main.log

    注意: irisowner ユーザーに RW 権限を追加するだけで十分なはずです。

    使用方法

    OpenAPI-Suite には、コードを「生成してダウンロード」するか「生成してインストール」するための Web インターフェースが備わっています。  

    このインターフェースは http://localhost:52796/openapisuite/ui/index.cspで使用できます(*必要に応じて、使用しているポート番号に変更してください)。  

    非常に簡単で、フォームに入力するだけです。

  • Application package name: 生成されるクラスに使用されるパッケージの名前です。  既存でないパッケージ名である必要があります。
  • What do you want to generate?: 生成するものを HTTP Client、Client Production、または REST server から選択します。
  • Namespace: コードが生成されるネームスペースを選択します。  「Install On Server」(サーバーにインストール)をクリックした場合にのみ意味があり、そうでない場合はこのフィールドは無視されます。
  • Web Application Name: Web アプリケーションはオプションであり、「REST Server」の生成を選択した場合にのみ利用できます。  生成される REST ディスパッチクラスに関連する Web アプリケーションを作成しない場合は、空のままにします。
  • OpenAPI specification field: 仕様を指している URL を入力するか、仕様自体をコピー/貼り付けします(後者の場合、仕様は JSON 形式である必要があります)。
  • 「Download Only」(ダウンロードのみ)ボタンをクリックした場合、コードは XML ファイルで生成されて返され、クラスはサーバーから削除されます。  生成されるクラスを一時的に保存するために使用するネームスペースは、OpenAPI-Suite がインストールされているネームスペースです(Docker インストールを使用した場合のデフォルトは IRISAPP です)。  

    ただし、「Install On Server」(サーバーにインストール)ボタンをクリックした場合、コードは生成・コンパイルされ、サーバーは、コード生成/コンパイルのステータス付きの JSON メッセージとログを返します。

    デフォルトではこの機能は無効化されていますが、有効にするには IRIS ターミナルを開いて以下を実行してください。

    Set^openapisuite.config("web","enable-install-onserver") = 1

    OpenAPI-Suite REST API を詳しく見る

    CSP フォームは、http://localhost:52796/openapisuite にある REST サービスを使用します。

    swagger-ui http://localhost:52796/swagger-ui/index.html を開き、http://localhost:52796/openapisuite/_spec を詳しく見てみましょう。

    これは、Angular フレームワークを使用してより高度なフロントエンドアプリケーションを作成するための第一歩です。

    コードをプログラミングで生成する

    もちろん、UI の使用は必須ではありません。このセクションでは、コードをプログラミングで生成し、生成されたサービスを使用する方法について説明します。

    すべてのスニペットは、dc.openapi.suite.samples.PetStore クラスでも使用できます。

    HTTP クライアント

    Set features("simpleHttpClientOnly") = 1Set sc = ##class(dc.openapi.client.Spec).generateApp("petstoreclient", "https://petstore3.swagger.io/api/v3/openapi.json", .features)

     

    最初の引数は、クラスが生成されるパッケージであるため、有効なパッケージ名を渡すようにしましょう。  2 つ目の引数は、仕様を指す URL、ファイル名、ストリーム、または %DynamicObject です。  「features」は配列であり、現在以下のサブスクリプトのみを使用できます。 

    simpleHttpClientOnly: 1 である場合、単純な HTTP クライアントのみが生成されます。そうでない場合、プロダクションも生成されます(デフォルトの動作)。

    compile: 0 である場合、生成されたコードはコンパイルされません。  エクスポートの目的のみでコードを生成する場合に便利です。  デフォルトは、compile = 1 です。

    以下は、生成したばかりの HTTP クライアントで「addPet」サービスを使用する例です。

    Set messageRequest = ##class(petstoreclient.requests.addPet).%New()
    Set messageRequest.%ContentType = "application/json"Do messageRequest.PetNewObject().%JSONImport({"id":456,"name":"Mittens","photoUrls":["https://static.wikia.nocookie.net/disney/images/c/cb/Profile_-_Mittens.jpg/revision/latest?cb=20200709180903"],"status":"available"})
    

    Set httpClient = ##class(petstoreclient.HttpClient).%New("https://petstore3.swagger.io/api/v3","DefaultSSL") ; MessageResponse will be an instance of petstoreclient.responses.addPetSet sc = httpClient.addPet(messageRequest, .messageResponse) If$$$ISERR(sc) Do$SYSTEM.Status.DisplayError(sc) Quit sc

    Write !,"Http Status code : ", messageResponse.httpStatusCode,! Do messageResponse.Pet.%JSONExport()

     
    クリックして生成されたクラスを表示します。
    <div class="spoiler-content" style="">
      <pre class="codeblock-container" idlang="0" lang="ObjectScript" tabsize="4"><code class="language-cls hljs cos"><span class="hljs-keyword">Class</span> petstoreclient.HttpClient <span class="hljs-keyword">Extends</span> <span class="hljs-built_in">%RegisteredObject</span> [ ProcedureBlock ]
    

    {

    Parameter SERVER = "https://petstore3.swagger.io/api/v3";Parameter SSLCONFIGURATION = "DefaultSSL";Property HttpRequest [ InitialExpression = {##class(%Net.HttpRequest).%New()} ];Property SSLConfiguration As%String [ InitialExpression = {..#SSLCONFIGURATION} ];Property Server As%String [ InitialExpression = {..#SERVER} ];Property URLComponents [ MultiDimensional ]; Method %OnNew(Server As%String, SSLConfiguration As%String) As%Status { Set:$Data(Server) ..Server = Server Set:$Data(SSLConfiguration) ..SSLConfiguration = SSLConfiguration Quit..InitializeHttpRequestObject() }

    Method InitializeHttpRequestObject() As%Status { Set..HttpRequest = ##class(%Net.HttpRequest).%New() Do##class(%Net.URLParser).Decompose(..Server, .components) Set:$Data(components("host"), host) ..HttpRequest.Server = host Set:$Data(components("port"), port) ..HttpRequest.Port = port Set:$$$LOWER($Get(components("scheme")))="https"..HttpRequest.Https = $$$YES, ..HttpRequest.SSLConfiguration = ..SSLConfigurationMerge:$Data(components) ..URLComponents = components Quit$$$OK }

    /// Implement operationId : addPet/// post /pet Method addPet(requestMessage As petstoreclient.requests.addPet, Output responseMessage As petstoreclient.responses.addPet = {##class(petstoreclient.responses.addPet).%New()}) As%Status { Set sc = $$$OK$$$QuitOnError(requestMessage.LoadHttpRequestObject(..HttpRequest)) $$$QuitOnError(..HttpRequest.Send("POST", $Get(..URLComponents("path")) _ requestMessage.%URL)) $$$QuitOnError(responseMessage.LoadFromResponse(..HttpRequest.HttpResponse, "addPet")) Quit sc } ... }

      <p>
         
      </p>
      
      <pre class="codeblock-container" idlang="0" lang="ObjectScript" tabsize="4"><code class="language-cls hljs cos"><span class="hljs-keyword">Class</span> petstoreclient.requests.addPet <span class="hljs-keyword">Extends</span> <span class="hljs-built_in">%RegisteredObject</span> [ ProcedureBlock ]
    

    {

    Parameter METHOD = "post";Parameter URL = "/pet";Property%ConsumeAs%String;Property%ContentTypeAs%String;Property%URLAs%String [ InitialExpression = {..#URL} ];/// Use this property for body content with content-type = application/json.
    /// Use this property for body content with content-type = application/xml.
    /// Use this property for body content with content-type = application/x-www-form-urlencoded.Property Pet As petstoreclient.model.Pet;/// Load %Net.HttpRequest with this property object. Method LoadHttpRequestObject(ByRef httpRequest As%Net.HttpRequest) As%Status { Set sc = $$$OKSet httpRequest.ContentType = ..%ContentTypeDo httpRequest.SetHeader("accept", ..%Consume) If$Piece($$$LOWER(..%ContentType),";",1) = "application/json"Do..Pet.%JSONExportToStream(httpRequest.EntityBody) If$Piece($$$LOWER(..%ContentType),";",1) = "application/xml"Do..Pet.XMLExportToStream(httpRequest.EntityBody) If$Piece($$$LOWER(..%ContentType),";",1) = "application/x-www-form-urlencoded" { ; To implement. この場合、コードの生成はまだありません。$$$ThrowStatus($$$ERROR($$$NotImplemented)) } Quit sc }

    }

      <p>
         
      </p>
      
      <pre class="codeblock-container" idlang="0" lang="ObjectScript" tabsize="4"><code class="language-cls hljs cos"><span class="hljs-keyword">Class</span> petstoreclient.responses.addPet <span class="hljs-keyword">Extends</span> petstoreclient.responses.GenericResponse [ ProcedureBlock ]
    

    {

    /// http status code = 200 content-type = application/xml/// http status code = 200 content-type = application/json/// Property Pet As petstoreclient.model.Pet;/// Implement operationId : addPet/// post /pet Method LoadFromResponse(httpResponse As%Net.HttpResponse, caller As%String = "") As%Status { Set sc = $$$OKDo##super(httpResponse, caller) If$$$LOWER($Piece(httpResponse.ContentType,";",1))="application/xml",httpResponse.StatusCode = "200" { $$$ThrowStatus($$$ERROR($$$NotImplemented)) } If$$$LOWER($Piece(httpResponse.ContentType,";",1))="application/json",httpResponse.StatusCode = "200" { Set..Pet = ##class(petstoreclient.model.Pet).%New() Do..Pet.%JSONImport(httpResponse.Data) Return sc } Quit sc }

    }

      <p>
         
      </p>
    </div>
    

     

    HTTP クライアントのプロダクション

    Set sc = ##class(dc.openapi.client.Spec).generateApp("petstoreproduction", "https://petstore3.swagger.io/api/v3/openapi.json")

    最初の引数は、単純な HTTP クライアントのコード生成をテストする場合のパッケージ名であるため、クライアントプロファクションの場合は必ず別のパッケージ名を使用してください。  2 つ目と 3 つ目も HTTP クライアントと同じルールが適用されます。

    テストする前に、以下のコマンドを使用して、管理ポータルからプロダクションを起動してください。

    Do##class(Ens.Director).StartProduction("petstoreproduction.Production")

    以下は、「addPet」サービスを使用する例ですが、今回は生成されたプロダクションを使用します。

    Set messageRequest = ##class(petstoreproduction.requests.addPet).%New()
    Set messageRequest.%ContentType = "application/json"Do messageRequest.PetNewObject().%JSONImport({"id":123,"name":"Kitty Galore","photoUrls":["https://www.tippett.com/wp-content/uploads/2017/01/ca2DC049.130.1264.jpg"],"status":"pending"})
    ; MessageResponse will be an instance of petstoreclient.responses.addPetSet sc = ##class(petstoreproduction.Utils).invokeHostSync("petstoreproduction.bp.SyncProcess", messageRequest, "petstoreproduction.bs.ProxyService", , .messageResponse)
    Write !, "Take a look in visual trace (management portal)"If$$$ISERR(sc) Do$SYSTEM.Status.DisplayError(sc)
    Write !,"Http Status code : ", messageResponse.httpStatusCode,!
    Do messageResponse.Pet.%JSONExport()

    次に、視覚的なトレースを開いて詳細を確認します。 

    packages モデル、リクエスト、およびレスポンスに生成されたクラスは、単純な HTTP クライアント用に生成されるコードと非常によく似ています。  パッケージリクエストのクラスは Ens.Request を継承し、パッケージレスポンスのクラスは Ens.Response を継承します。  ビジネスオペレーションのデフォルトの実装は非常に単純です。以下のスニペットをご覧ください。 

    Class petstoreproduction.bo.Operation Extends Ens.BusinessOperation [ ProcedureBlock ]
    {
    
    Parameter ADAPTER = "EnsLib.HTTP.OutboundAdapter";Property Adapter As EnsLib.HTTP.OutboundAdapter;/// Implement operationId : addPet/// post /pet
    Method addPet(requestMessage As petstoreproduction.requests.addPet, Output responseMessage As petstoreproduction.responses.addPet) As%Status
    {
        Set sc = $$$OK, pHttpRequestIn = ##class(%Net.HttpRequest).%New(), responseMessage = ##class(petstoreproduction.responses.addPet).%New()
        $$$QuitOnError(requestMessage.LoadHttpRequestObject(pHttpRequestIn))
        $$$QuitOnError(..Adapter.SendFormDataArray(.pHttpResponse, "post", pHttpRequestIn, , , ..Adapter.URL_requestMessage.%URL))
        $$$QuitOnError(responseMessage.LoadFromResponse(pHttpResponse, "addPet"))
        Quit sc
    }
    ...
    }
    }

     

    HTTP サーバーサイド REST アプリケーション

    Set sc = ##class(dc.openapi.server.ServerAppGenerator).Generate("petstoreserver", "https://petstore3.swagger.io/api/v3/openapi.json", "/petstore/api")

    最初の引数は、クラスを生成するパッケージ名です。  2 つ目は HTTP クライアントと同じルールが適用されます。  3 つ目の引数は必須ではありませんが、使用されている場合、Web アプリケーションが指定された名前で作成されます(有効な Web アプリケーション名を指定することに注意してください)。

    クラス petstoreserver.disp(ディスパッチ %CSP.REST クラス)は、^%REST が生成するコードに似ており、リクエストを受け入れるか拒否する多数のチェックを実行し、petstoreserver.impl で関連するサービス ClassMethod 実装を呼び出します。  主な違いは、実装メソッドに渡される引数で、これは petstoreserver.requests オブジェクトです。 例:

    Class petstoreserver.disp Extends%CSP.REST [ ProcedureBlock ]
    {
    

    Parameter CHARSET = "utf-8";Parameter CONVERTINPUTSTREAM = 1;Parameter IgnoreWrites = 1;Parameter SpecificationClass = "petstoreserver.Spec";/// Process request post /petClassMethod addPet() As%Status { Set sc = $$$OKTry{ Set acceptedMedia = $ListFromString("application/json,application/xml,application/x-www-form-urlencoded") If '$ListFind(acceptedMedia,$$$LOWER(%request.ContentType)) { Do##class(%REST.Impl).%ReportRESTError(..#HTTP415UNSUPPORTEDMEDIATYPE,$$$ERROR($$$RESTContentType,%request.ContentType)) Quit } Do##class(%REST.Impl).%SetContentType($Get(%request.CgiEnvs("HTTP_ACCEPT"))) If '##class(%REST.Impl).%CheckAccepts("application/xml,application/json") Do##class(%REST.Impl).%ReportRESTError(..#HTTP406NOTACCEPTABLE,$$$ERROR($$$RESTBadAccepts)) QuitIf '$isobject(%request.Content) Do##class(%REST.Impl).%ReportRESTError(..#HTTP400BADREQUEST,$$$ERROR($$$RESTRequired,"body")) QuitSet requestMessage = ##class(petstoreserver.requests.addPet).%New() Do requestMessage.LoadFromRequest(%request) Set scValidateRequest = requestMessage.RequestValidate() If$$$ISERR(scValidateRequest) Do##class(%REST.Impl).%ReportRESTError(..#HTTP400BADREQUEST,$$$ERROR(5001,"Invalid requestMessage object.")) QuitSet response = ##class(petstoreserver.impl).addPet(requestMessage) Do##class(petstoreserver.impl).%WriteResponse(response) } Catch(ex) { Do##class(%REST.Impl).%ReportRESTError(..#HTTP500INTERNALSERVERERROR,ex.AsStatus(),$parameter("petstoreserver.impl","ExposeServerExceptions")) } Quit sc } ... }

    ご覧のとおり、dispatch クラスは実装メソッドを呼び出す前に「LoadFromRequest」と「RequestValidate」を呼び出しています。  これらのメソッドにはデフォルトの実装がありますが、コードジェネレーターはすべてのケースに対応できません。  現時点では、「query」、「headers」、「path」、およびコンテンツタイプが「application/json」、「application/octet-stream」、または「multipart/form-data」である body で最も一般的なケースがパラメーターとして自動的に処理されます。  開発者は、必要に応じて実装をチェック/完了する必要があります(未対応のケースについては、デフォルトでは、コードジェネレーターは $$$ThrowStatus($$$ERROR($$$NotImplemented)) を設定します)。

     
    リクエストクラスの例:
    Class petstoreserver.requests.addPet Extends%RegisteredObject [ ProcedureBlock ]
    {
    

    Parameter METHOD = "post";Parameter URL = "/pet";Property%ConsumeAs%String;Property%ContentTypeAs%String;Property%URLAs%String [ InitialExpression = {..#URL} ];/// Use this property for body content with content-type = application/json.
    /// Use this property for body content with content-type = application/xml.
    /// Use this property for body content with content-type = application/x-www-form-urlencoded.Property Pet As petstoreserver.model.Pet;/// Load object properties from %CSP.Request object. Method LoadFromRequest(request As%CSP.Request = {%request}) As%Status { Set sc = $$$OKSet ..%ContentType = $Piece(request.ContentType, ";", 1) If ..%ContentType = "application/json"{ Do..PetNewObject().%JSONImport(request.Content) } If ..%ContentType = "application/xml" { ; To implement. There is no code generation yet for this case.$$$ThrowStatus($$$ERROR($$$NotImplemented)) } If ..%ContentType = "application/x-www-form-urlencoded" { ; To implement. There is no code generation yet for this case.$$$ThrowStatus($$$ERROR($$$NotImplemented)) } Quit sc }

    /// Load object properties from %CSP.Request object. Method RequestValidate() As%Status { Set sc = $$$OK$$$QuitOnError(..%ValidateObject()) If ''$ListFind($ListFromString("application/json,application/xml,application/x-www-form-urlencoded"), ..%ContentType) { Quit:..Pet=""$$$ERROR(5659, "Pet") } If$IsObject(..Pet) $$$QuitOnError(..Pet.%ValidateObject()) Quit sc }

    }

    <p>
       
    </p>
    

     

    ^%REST の使用方法と同じように、「petstoreserver.impl」クラスには、サービスに関連したすべてのメソッドが含まれており、開発者が実装する必要があります。 

    Class petstoreserver.impl Extends%REST.Impl [ ProcedureBlock ]
    {
    
    Parameter ExposeServerExceptions = 1;/// Service implemntation for post /petClassMethod addPet(messageRequest As petstoreserver.requests.addPet) As%Status
    {
        ; Implement your service here.; Return {}$$$ThrowStatus($$$ERROR($$$NotImplemented))
    }
    
    ...
    }

     

    生成されたパッケージの短い説明

      <td>
        タイプ
      </td>
      
      <td>
        説明
      </td>
    </tr>
    
    <tr>
      <td>
        petstoreclient.model petstoreproduction.model
      </td>
      
      <td>
        クライアントサイドとサーバーサイド
      </td>
      
      <td>
        すべてのモデルが含まれます。  これらのクラスは、JSON から簡単にオブジェクトを読み込めるように %JSON.Adaptor を拡張します。   プロダクションが生成されると、これらのクラスは %Persistent も拡張します。
      </td>
    </tr>
    
    <tr>
      <td>
        petstoreclient.requests   petstoreproduction.requests
      </td>
      
      <td>
        クライアントサイドとサーバーサイド
      </td>
      
      <td>
        %Net.HttpRequest を簡単に初期化するために使用されるオブジェクト。  仕様にはオペレーションごとのクラスが定義されています。プロダクションが生成される場合、これらのクラスは Ens.Request を拡張します。 注意: このクラスの実装は、生成対象がサーバーサイドであるかクライアントサービスであるかによって異なります。  クライアントサイドの場合、すべてのクラスには「LoadHttpRequestObject」メソッドが含まれるため、このクラスプロパティから「%Net.HttpRequest」を読み込むことができます。 クラスがサーバーサイドを対象に生成される場合、「%request」オブジェクトからインスタンスを読み込むために、各クラスに「LoadFromRequest」メソッドが含まれています。
      </td>
    </tr>
    
    <tr>
      <td>
        petstoreclient.responses petstoreproduction.responses
      </td>
      
      <td>
        クライアントサイドとサーバーサイド
      </td>
      
      <td>
        petstoreclient.requests の 逆です。  %Net.HttpRequest のレスポンスを処理できます。プロダクションが生成される場合、これらのクラスは Ens.Response を拡張します。
      </td>
    </tr>
    
    <tr>
      <td>
        petstoreclient.HttpClient
      </td>
      
      <td>
        クライアントサイド
      </td>
      
      <td>
        HTTP リクエストを実行するためのすべてのメソッドが含まれます。OpenAPI 仕様で定義されるオペレーションごとに 1 つのメソッドがあります。
      </td>
    </tr>
    
    <tr>
      <td>
        petstoreproduction. bo.Operation
      </td>
      
      <td>
        クライアントサイド
      </td>
      
      <td>
        オペレーションクラスには、OpenAPI 仕様で定義されたオペレーションごとに 1 つのメソッドがあります。
      </td>
    </tr>
    
    <tr>
      <td>
        petstoreproduction.bp
      </td>
      
      <td>
        クライアントサイド
      </td>
      
      <td>
        同期と非同期の 2 つのデフォルトのビジネスプロセスが定義されています。
      </td>
    </tr>
    
    <tr>
      <td>
        petstoreproduction.bs
      </td>
      
      <td>
        クライアントサイド
      </td>
      
      <td>
        実装するすべての空のビジネスサービスが含まれます。
      </td>
    </tr>
    
    <tr>
      <td>
        petstoreproduction.Production
      </td>
      
      <td>
        クライアントサイド
      </td>
      
      <td>
        プロダクション構成の設定。
      </td>
    </tr>
    
    <tr>
      <td>
        petstoreserver.disp
      </td>
      
      <td>
        サーバーサイド
      </td>
      
      <td>
        クラス dispatch %CSP.REST
      </td>
    </tr>
    
    <tr>
      <td>
        petstoreserver.Spec
      </td>
      
      <td>
        サーバーサイド
      </td>
      
      <td>
        このクラスには、XData ブロックに OpenAPI 仕様が含まれています。
      </td>
    </tr>
    
    <tr>
      <td>
        petstoreserver.impl
      </td>
      
      <td>
        サーバーサイド
      </td>
      
      <td>
        これには、OpenAPI 仕様で定義されたオペレーションに関連するすべての空のメソッドが含まれています。  これが、開発者がサービスを実装する必要のあるクラス(%REST.Impl を拡張)です。
      </td>
    </tr>
    
    パケージ名 / クラス名

    開発ステータス

    OpenAPI-Suite はまだ非常に未熟な製品であり、さらに多くのテストを実施した上での改善が必要です。  OpenAPI 3 のサポートは部分的であり、さらに多くの機能がサポートされる可能性があります。 

    テストは公開されている仕様 https://petstore3.swagger.io/api/v3/openapi.json と比較的に単純な 2 つの仕様を使って実施されました。  もうちろん、すべてのケースに対応するには不十分です。  仕様を共有していただければ、喜んでテストに使用させていただきます。

    このプロジェクトの基盤は十分であり、AsyncAPI をサポートするように拡張するなど、簡単に進化させることができると考えています。

    お気軽にフィードバックをお寄せください。

    このアプリケーションをご利用いただき、開発者ツールコンテストで支援していただければ幸いです。

    お読みいただきありがとうございました。