このドキュメントでは、GeneXus で REST Web サービスとして公開されているビジネスコンポーネントを使用してデータを更新する方法について説明します。
最初に、基本的な手引きを示します:
HttpClient データタイプを使用します。
2 つのメソッドを実行する必要があります:
- HTTP の GET 動詞の主キーを使用してデータを取得し、MD5 ハッシュとデータの関連付けを維持します。これは、「REST サービスとして公開されているビジネスコンポーネントからデータを取得する方法」の説明とよく似ています。
- HTTP の PUT 動詞を使用してデータを更新します。テーブル構造のすべてのデータに加え、HTTP リクエストの本文に gx_md5_hash を含める必要があります。これは、トランザクションを使用する際に、GeneXus が使用する疑似会話ダイアログを模倣する必要があるためです。レコードを更新するには、HTTP の PUT 動詞の本文にビジネスコンポーネントの構造全体とハッシュ値を含める必要があります。このハッシュ値は、並行処理のコントロールに使用されます。メッセージの本文は JSON 形式にし、HTTP GET を実行したときに返されるのと同じビジネスコンポーネント構造が含まれていなければなりません。
HTTP POST の場合と同様に、HTTP の PUT 動詞を実行するときは、主キーの値をクエリ文字列に追加する必要があります。
次の例では、請求書を更新します (これは 2 段階のトランザクションです)。ビジネスコンポーネントは REST サービスとして公開されています。
この例では、請求書を更新して行を追加します。
次の 2 つの手順を実行します:
- 更新するレコードを取得し (InvoiceId=1)、レコードのほかのデータとともに gx_md5_hash データを取り出します。データは &HTTClient.ToString メソッドで取り出し、&result という文字列変数に一時的に格納します。
&httpclient.Host= &server
&httpclient.Port = &port
&httpclient.BaseUrl = &urlbase
&httpclient.Execute('GET','Invoice/1')
if &httpclient.StatusCode = 200
&result = &httpclient.ToString()
else
msg("There was an error retrieving the data: " + &httpclient.StatusCode.ToString())
endif
- 上記のコードに、データ取得後に HTTP の応答を取り出し (HASH データを含む)、SDT 構造に格納するコードを追加します。この構造は次のようになります (Invoice の構造に基づいていますが、gx_md5_hash のフィールドが含まれます):
&httpclient.Host= &server
&httpclient.Port = &port
&httpclient.BaseUrl = &urlbase
&httpclient.Execute('GET','Invoice/1')
if &httpclient.StatusCode = 200
&result = &httpclient.ToString()
&invoicesdt.FromJson(&result) //&invoicesdt には gx_md5_hash の情報を読み込み済み
&invoicesdtlevel = new() //新しい行を追加...、
&invoicesdtlevel.InvoiceLineCod = 4
&invoicesdtlevel.ProductCod = 1
&invoicesdt.InvoiceLevel.Add(&invoicesdtlevel)
&addstring = &invoicesdt.ToJson() //JSON 形式へ..
&httpclient.AddString(&addstring)
&httpclient.AddHeader('content-type','application/json') // 必要なヘッダーを追加
&httpclient.Execute('PUT','Invoice/1')
if &httpclient.StatusCode = 200
msg("Data successfully added")
else
msg("There was an error udapting the data: " + &httpclient.StatusCode.ToString())
endif
else
msg("There was an error retrieving the data: " + &httpclient.StatusCode.ToString())
endif
この例では、主キーも本文内で送信しています。この処理は GeneXus X Evolution 3 まで必要です。
このサンプルは「File:Sample Update Rest services」からダウンロードできます。
注:
- 複数のパラメーターを URL で渡す場合は (複合主キー)、コンマで区切る必要があります。
- サービス URI が "http://localhost/TestRESTFullGX.NetEnvironment/rest/Product" の場合、ベース URL は次のようになります: "/TestRESTFullGX.NetEnvironment/rest/"
- 呼び出し後、エラー処理を管理するために、HTTP ステータスコードのクエリが行われます。
{"error":{"code":"500","message":"受信メッセージは予期しないメッセージ形式 'Raw' です。この操作に対して予期されていたメッセージ形式は 'Xml'; 'Json' です。これは、バインドに WebContentTypeMapper が設定されていないことが原因である可能性があります。詳細については、WebContentTypeMapper のドキュメントを参照してください。"}}
理由は、リクエストに適切なヘッダーがないことです。ヘッダー 'content-type: application/json' を追加します。
- TCPtrace などのツールを使用すると、HTTP のトラフィックを確認し、問題を検出するのに役立ちます。プロキシのように機能するので、使用は簡単です。呼び出しを TCPtrace がリッスンするポートとホストにリダイレクトするだけで、TCPtrace がサービス URL をポイントします。
- また、エラーに関する詳細情報が必要な場合は、次の HTTPClient データタイプのメソッドを使用して、呼び出しの出力を印刷できます:
&httpclient.Execute('PUT','Invoice/1')
&httpstatus = &httpclient.StatusCode
msg('Http status: ' + &httpstatus,status)
&result = &httpclient.ToString()
msg('Output: ',status)
msg('=========',status)
msg(&result,status)
次の内容が印刷されます:
Http status: 200
Output:
========= {"InvoiceCod":1,"InvoiceDate":"2016-03-01","CustomerCod":"C56A4180-65AA-42EC-A945-5FD21DEC0538","CustomerName":"juan","InvoiceLevel": [ {"InvoiceLineCod":1,"ProductCod":1,"ProductName":"product1","ProductPrice":12.0000},{"InvoiceLineCod":4,"ProductCod":1,"ProductName":"product1","ProductPrice":12.0000} ] ,"gx_md5_hash":"4C921FA040E330D0EF68F96354420A79"}
注:
REST サービスの利用については (GeneXus で生成可能かどうかにかかわらず)、GeneXus は OpenAPI インポートツールを提供します。
|