Apex REST 勉強メモ：コールアウト

#1.Apex REST コールアウトの基本
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/332907/e12de2fc-3489-0ad6-fba4-b01b1c372b74.png)

#2.一般的な HTTP メソッドについて説明します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/332907/29dcad3b-25da-3493-a71a-e95acda89790.png)

#3.HttpRequest の Wrapper クラス実装例
```java
public class HttpClient {
    private HttpRequest request;
    private String endpoint;
    
    public Map<String, String> headers      {get; set;}
    public Map<String, String> parameters   {get; set;}
    public Object requestBody               {get; set;}
    
    public HttpClient(String namedCredential, String endpointPath) {
        this('callout:' + namedCredential + endpointPath);
    }

    public HttpClient(String endpoint) {
        this.endpoint = endpoint;
        this.headers    = new Map<String, String>();
        this.parameters = new Map<String, String>();
        this.request    = new HttpRequest();
    }

    public HttpResponse del() {
        return this.callout('DELETE');
    }

    public HttpResponse get() {
        return this.callout('GET');
    }

    public HttpResponse head() {
        return this.callout('HEAD');
    }

    public HttpResponse patch() {
        return this.callout('PATCH');
    }

    public HttpResponse post() {
        return this.callout('POST');
    }

    public HttpResponse put() {
        return this.callout('PUT');
    }

    public HttpResponse trace() {
        return this.callout('TRACE');
    }
    
    public void setTimeout(Integer timeoutMs) {
        this.request.setTimeout(timeoutMs);
    }
    
    public void setCompressed(Boolean compress) {
        this.request.setCompressed(compress);
    }
    
    private HttpResponse callout(String httpVerb) {
        this.request.setMethod(httpVerb);
        this.setHeaders();
        this.setEndpointAndParameters();
        this.setRequestBody();

        return new Http().send(request);
    }

    private void setHeaders() {
        for(String headerKey : this.headers.keySet()) {
            this.request.setHeader(headerKey, this.headers.get(headerKey));
        }
    }

    private void setEndpointAndParameters() {
        String parameterString = '';
        for(String parameterKey : this.parameters.keySet()) {
            String paremeterDelimiter = String.isEmpty(parameterString) && !this.endpoint.contains('?') ? '?' : '&';
            parameterString += paremeterDelimiter + parameterKey + '=' + this.parameters.get(parameterKey);
        }
        this.request.setEndpoint(this.endpoint + parameterString);
    }

    private void setRequestBody() {
        if(this.requestBody == null) return;
        
        Boolean contentTypeNotSet = this.headers.get('Content-Type') == null;
        if(this.requestBody instanceOf Blob) {
            this.request.setBodyAsBlob((Blob)this.requestBody);
            if(contentTypeNotSet) this.request.setHeader('Content-Type', 'multipart/form-data; charset=utf-8');
        } else if(this.requestBody instanceOf Dom.Document) {
            this.request.setBodyDocument((Dom.Document)this.requestBody);
            if(contentTypeNotSet) this.request.setHeader('Content-Type', 'text/xml; charset=utf-8');
        } else {
            this.request.setBody(Json.serialize(this.requestBody));
            if(contentTypeNotSet) this.request.setHeader('Content-Type', 'application/json; charset=utf-8');
        }
    }
}
```
#4.状況コードとエラー応答
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/332907/a4013dcb-56c8-a8ed-7a50-b07761cbc56c.png)

#5.Resource
-[Salesforceから外部APIを叩く(JSONの解析)](https://qiita.com/one-kelvin/items/3d382bec836ad13d4c46)
- [HttpRequest クラス](https://developer.salesforce.com/docs/atlas.ja-jp.apexcode.meta/apexcode/apex_classes_restful_http_httprequest.htm#apex_classes_restful_http_httprequest)
- [HttpResponse クラス](https://developer.salesforce.com/docs/atlas.ja-jp.apexcode.meta/apexcode/apex_classes_restful_http_httpresponse.htm#apex_classes_restful_http_httpresponse)
- [JSON クラス](https://developer.salesforce.com/docs/atlas.ja-jp.apexcode.meta/apexcode/apex_class_System_Json.htm#apex_class_System_Json)
- [JSONGeneratorクラス調査メモ(Apex)](https://qiita.com/shinsaka/items/06b0f3019866d196daee)
- [Trailhead：Apex REST コールアウト](https://trailhead.salesforce.com/ja/content/learn/modules/apex_integration_services/apex_integration_rest_callouts)
- [Apex 開発者ガイド：HttpResponse クラス](https://trailhead.salesforce.com/ja/content/learn/modules/apex_integration_services/apex_integration_rest_callouts)
- [状況コードとエラー応答](https://developer.salesforce.com/docs/atlas.ja-jp.api_rest.meta/api_rest/errorcodes.htm)
- https://github.com/jongpie/ApexCallouts/tree/master/src/classes
- https://github.com/open-force/Httpex/tree/master/src/classes