Apex Rest APIで任意のステータスコードを返す

カスタムでApex Rest APIを作成する際にレスポンスにステータスコードを反映させる方法。

概要

今までは、返却用するJSON用のクラスを作成し、そのクラスを返却していたのだが、
そもそも返却の方法としてはそれが正しくなかった(お作法に則っていなかった)よう。

[salesforce]Apex REST作成時のtips
この辺の記事内で返却しているやり方。

実際には、returnで結果を返す必要はなく、RestResponseクラスに追加してやるだけでよかった。

RestResponse

ステータスコード

ステータスコードの指定は以下のようにする。

1
2
RestResponse res = RestContext.response;
res.statusCode = 400;

ヘッダ情報

デフォルトの情報だと、Content-Typeapplication/octetstreamになっているようなので、application/jsonに変更したい。
ヘッダ情報の追加・変更は以下のようにする。

1
2
RestResponse res = RestContext.response;
res.addHeader('Content-Type', 'application/json');

レスポンス内容

レスポンスの内容をJSONで返す場合、作成した返却用クラスをJSONにパースし、Blobにキャストして追加してやる。

1
2
3
4
ResultData result = new ResultData();

RestResponse res = RestContext.response;
res.responseBody = Blob.valueOf(JSON.serialize(result));

コード

上記をまとめると以下のような形になる。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
@RestResource(urlMapping='/your/api')
global with sharing class Your_Apex_Class  {

  @HttpPost
  global static void something_method() {
    ResultData result = new ResultData();
    result.success = false;
    ResultError error = new ResultError();
    result.error = error;
  
    RestResponse res = RestContext.response;
    res.addHeader('Content-Type', 'application/json');
    // (中略)
  
    if(/* エラーの場合 */){
      error.message = 'エラーメッセージ';
      res.statusCode = 400;
      res.responseBody = Blob.valueOf(JSON.serialize(result));
      return;
    }
  
    // (中略)
    result.success = true;
    res.statusCode = 200;
    res.responseBody = Blob.valueOf(JSON.serialize(result));
    return;
  }
  
  global class ResultData{
    global Boolean success;
    global ResultError error;
  }
  
  global class ResultError{
    global String message;
  }
} 

エラー発生時にはステータスコードが400で以下のようなJSONが返却される。

1
2
3
4
5
6
{
  "success": false,
  "error": {
      "message": "エラーメッセージ"
  }
}

テスト

テストクラスを書く際に、送信結果を取得する場合には以下のようにする。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
@isTest static void your_something_test() {
  String json_str = '{ "YOUR" : "JSON_DATA" }';

  //あらかじめ宣言が必要
  RestRequest req = new RestRequest();
  req.requestBody = Blob.valueof(json_str);
  RestContext.request = req;
  RestResponse res = new RestResponse();
  RestContext.response = res;
  
  Your_Apex_Class.something_method(); //実行
  
  System.assertEquals(res.statusCode, 400); //ステータスコード
  //返却されたJSON文字列をMapにキャストする
  Map<String, Object> requestBody = (Map<String, Object>)JSON.deserializeUntyped(res.responseBody.ToString());
  Map<String, Object> errorBody = (Map<String, Object>)requestBody.get('error');
  System.assertEquals(errorBody.get('message'), 'エラーメッセージ'); //エラーメッセージ
}

参考

   このエントリーをはてなブックマークに追加