REST APIの引数について

スポンサーリンク

カスタムREST APIを作成

まずは、REST APIを作成します。
REST API自体標準機能が備わっていいますが、今回は引数の検証がしたいので自作で作ります。
REST APIを作る場合、@RestResourceアノテーションと対応するHTTPメソッド用のアノテーションを使用します。
今回はPOSTで検証したいので、ソースコードはこのようになります。

HogeApi.cls

@RestResource(urlMapping='/Hoge/*')
global with sharing class HogeApi {
    @HttpPost
    global static String doPost(String name, Integer count, Boolean isHello) {
        String helloStr = '';
        String greet = isHello ? 'Hello' : 'Goodbye';
        for(Integer i = 0; i < count; i++){
            helloStr += greet + ' ' +name + '!';
        }
        return helloStr;
    }
}

ちょっとだけ解説すると、@RestResourceアノテーションでカスタムのREST APIを作るよっていう宣言をします。
urlMappingで指定されたものがAPI URLになります。
urlMappingはhttps://instance.salesforce.com/services/apexrest以降を指定するため、
上記ソースでのAPI URLはhttps://instance.salesforce.com/services/apexrest/Hogeになります。

あとはHttpメソッドに対応するメソッドをクラス内に用意します。
今回はPOSTだけですが、GETを使用したければ、@HttpGetアノテーションをつけてメソッドを定義、PUTやDELETEも同じように使用します。

JSON形式での引数指定

早速作ったAPIでRESTを確認してみましょう。
今回はお手軽なWorkbenchを使用します。
utirityのREST ExplorerからRequest HeadersとRequest Bodyをこのようにします。

Request Headers

Content-Type:application/json; charset=UTF-8
Accept:application/xml

Request Body

{
“name”:”hoge”,
“count”:2,
“isHello”:true
}

Executeで実行すると結果はこのように。

REST ExplorerでのJSON形式実行結果

Raw Response

HTTP/1.1 200 OK Date: Sat, 27 Oct 2018 06:34:03 GMT Strict-Transport-Security: max-age=31536000; includeSubDomains X-Content-Type-Options: nosniff X-XSS-Protection: 1; mode=block Content-Security-Policy: upgrade-insecure-requests X-Robots-Tag: none Cache-Control: no-cache,must-revalidate,max-age=0,no-store,private Set-Cookie: BrowserId=6fZOKEZFRviCi6PQewAasA;Path=/;Domain=.salesforce.com;Expires=Wed, 26-Dec-2018 06:34:03 GMT;Max-Age=5184000 Expires: Thu, 01 Jan 1970 00:00:00 GMT Content-Type: application/xml;charset=UTF-8 Transfer-Encoding: chunked
<?xml version=”1.0″ encoding=”UTF-8″?> <response> Hello hoge!Hello hoge!</response>

この通り、成功しています。
ここでのポイントは、引数に文字列、数値、Boolean型をそれぞれ使用していますが、JSONで指定する時のダブルクォートの有無。
数値、Boolean型にはダブルクォートはつきませんので注意しましょう。

また、JSONを以下のように順番を変えても結果は同じでした。

{
“count”:2,
“isHello”:true,
“name”:”hoge”
}

どうやら、名前がマッチしていれば順番は関係ないようです。

今後は大文字、小文字を変えてみました。

{
“count”:2,
ishello“:true,
“name”:”hoge”
}

Raw Response

HTTP/1.1 400 Bad Request Date: Sat, 27 Oct 2018 06:48:14 GMT Strict-Transport-Security: max-age=31536000; includeSubDomains X-Content-Type-Options: nosniff X-XSS-Protection: 1; mode=block Content-Security-Policy: upgrade-insecure-requests X-Robots-Tag: none Cache-Control: no-cache,must-revalidate,max-age=0,no-store,private Set-Cookie: BrowserId=XiOKfTMaQnaOnNw3qcdCgA;Path=/;Domain=.salesforce.com;Expires=Wed, 26-Dec-2018 06:48:14 GMT;Max-Age=5184000 Expires: Thu, 01 Jan 1970 00:00:00 GMT Content-Type: application/xml;charset=UTF-8 Transfer-Encoding: chunked
<?xml version=”1.0″ encoding=”UTF-8″?> <Errors> <Error> <errorCode>JSON_PARSER_ERROR</errorCode> <message>Unexpected parameter encountered during deserialization: ishello at [line:3, column:19]</message> </Error> </Errors>

はい、エラーです。
どうやら大文字小文字は区別するみたいですね。

XML形式での引数指定

次はXML形式で引数を指定してみます。
Request HeadersとRequest Bodyはこのように入力します

Request Headers

Content-Type:application/xml; charset=UTF-8
Accept:application/xml

Request Body

<request>
<name>Hoge</name>
<count>2</count>
<isHello>true</isHello>
</request>

そして結果はこの通り。
REST ExplorerでのXML形式実行結果

Raw Response

HTTP/1.1 200 OK Date: Sat, 27 Oct 2018 07:15:50 GMT Strict-Transport-Security: max-age=31536000; includeSubDomains X-Content-Type-Options: nosniff X-XSS-Protection: 1; mode=block Content-Security-Policy: upgrade-insecure-requests X-Robots-Tag: none Cache-Control: no-cache,must-revalidate,max-age=0,no-store,private Set-Cookie: BrowserId=qZqjJ4UES8Cd8_FRUWCokQ;Path=/;Domain=.salesforce.com;Expires=Wed, 26-Dec-2018 07:15:50 GMT;Max-Age=5184000 Expires: Thu, 01 Jan 1970 00:00:00 GMT Content-Type: application/xml;charset=UTF-8 Transfer-Encoding: chunked
<?xml version=”1.0″ encoding=”UTF-8″?> <response> Hello hoge!Hello hoge!</response>

同じ引数なので同じ結果になりますが、こちらも問題なく動いています。
こちらもJSON形式と同様、順番の入れ替えはOK、大文字小文字は区別します。
こちらは、XML形式なので、ダブルクォートでくくる必要ななく、文字列型であっても、数値型であっても、Boolean型であっても、タグの中に値を記載すればOKです。

ちょっと複雑にしてみる

今後はAPIクラスをちょっと変更して、引数をクラスにします。
HogeApi.cls

@RestResource(urlMapping='/Hoge/*')
global with sharing class HogeApi {
    @HttpPost
    global static String doPost(HogeHello hoge) {
        String helloStr = '';
        String greet =hoge.isHello ? 'Hello' : 'Goodbye';
        for(Integer i = 0; i < hoge.count; i++){
            helloStr += greet + ' ' +hoge.name + '!';
        }
        return helloStr;
    }
    global class HogeHello{
        global String name;
        global Integer count;
        global Boolean isHello;
    }
}

この場合の引数指定でも、JSON、XMLともに階層化してあげればOKです。

JSON形式

{
“hoge”:{
“name”:”hoge”,
“count”:2,
“isHello”:true
}
}

XML形式

<request>
<hoge>
<name>Hoge</name>
<count>2</count>
<isHello>true</isHello>
</hoge>
</request>

まとめ

  • 大文字・小文字は区別する
  • JSON、XMLとも順番は関係ない
  • JSON形式では、文字列はダブルクォートでくくり、数値やBooleanはくくらない
  • XML形式では、どのデータ型であってもダブルクォートでくくる必要ななく、タグの中に値を記載する

コメント