Qiita Teams that are logged in
You are not logged in to any team

Log in to Qiita Team
Community
OrganizationAdvent CalendarQiitadon (β)
Service
Qiita JobsQiita ZineQiita Blog
14
Help us understand the problem. What is going on with this article?
@one-kelvin

Salesforceから外部APIを叩く(JSONの解析)

More than 3 years have passed since last update.

ApexクラスからRandom User GeneratorのAPI(以下、RandomUserAPI)を叩き、リードに登録してみます。

※リードは潜在的な顧客として認識された人や会社を登録するためのオブジェクトなのでリードの使い方としては誤りです。テストクラスでテストデータを作るくらいのイメージでやっています。

RandomUserAPIについて

https://randomuser.me/api/にアクセスすると、以下のようなJSONが返ってきます。

{
    "results": [
        {
            "gender": "female",
            "name": {
                "title": "mademoiselle",
                "first": "olivia",
                "last": "lefebvre"
            },
            "location": {
                "street": "3819 avenue du château",
                "city": "st-barthélemy vd",
                "state": "basel-stadt",
                "postcode": 9956
            },
            "email": "olivia.lefebvre@example.com",
            "login": {
                "username": "greenmeercat253",
                "password": "opus",
                "salt": "5SGUWEbt",
                "md5": "559227b3c1722b2448e959658109a443",
                "sha1": "ef650448a47cef7e3d483cb8bf857ad1794bf0c3",
                "sha256": "0a264913c6bace08d8a6fd6c40a8dae6885042a50ae0c4add868b5570d36a65b"
            },
            "dob": "1967-12-07 06:42:54",
            "registered": "2007-05-13 04:55:23",
            "phone": "(441)-746-6416",
            "cell": "(704)-379-7611",
            "id": {
                "name": "AVS",
                "value": "756.JOKA.MGZG.65"
            },
            "picture": {
                "large": "https://randomuser.me/api/portraits/women/85.jpg",
                "medium": "https://randomuser.me/api/portraits/med/women/85.jpg",
                "thumbnail": "https://randomuser.me/api/portraits/thumb/women/85.jpg"
            },
            "nat": "CH"
        }
    ],
    "info": {
        "seed": "e9bc4458117a7c8d",
        "results": 1,
        "page": 1,
        "version": "1.1"
    }
}

デフォルトでは1人分の名前や電話番号といった情報が入りますが、How to useによると人数や出身地域を指定できるオプションがあるようなので、今回は人数、フォーマット、出身地域を指定してみます。

やってみる

コード全体

public static void insertRandomUsers() {
    HttpRequest request = new HttpRequest();
    request.setEndpoint('https://randomuser.me/api/?results=10&format=JSON&nat=us');
    request.setMethod('GET');

    Http http = new Http();
    HttpResponse response = new HttpResponse();
    response = http.send(request);

    Map<String, Object> requestBody = new Map<String, Object>();
    Integer statusCode = response.getStatusCode();
    if (statusCode == 200) {
        requestBody = (Map<String, Object>)JSON.deserializeUntyped(response.getBody());
    } else {
        System.debug('Error : ' + statusCode + ' => ' + response.getBody());
        return;
    }

    List<Lead> leadList = new List<Lead>();
    for (Object result : (List<Object>)requestBody.get('results')) {
        Map<String, Object> user = (Map<String, Object>)result;
        Map<String, Object> name = (Map<String, Object>)user.get('name');

        Lead l = new Lead();
        l.firstName = String.valueOf(name.get('first'));
        l.lastName = String.valueOf(name.get('last'));
        l.phone = String.valueOf(user.get('phone'));
        l.Company = String.valueOf(user.get('email'));

        leadList.add(l);
    }
    insert leadList;
}

GETでAPIを叩く

  • httpRequestオブジェクトに対してsetEndPoint()でURLを指定
  • httpRequestオブジェクトに対してsetMethod()でリクエストメソッドを指定
  • httpオブジェクトのsend()メソッドでhttpResponseオブジェクトが返ってくる

という流れになります。

HttpRequest request = new HttpRequest();
request.setEndpoint('https://randomuser.me/api/?results=10&format=JSON&nat=us');
request.setMethod('GET');

Http http = new Http();
HttpResponse response = new HttpResponse();
response = http.send(request);

responseBodyの解析

GETした内容から名前や電話番号を取ってきてLeadオブジェクトにセットしたいわけですが、これが非常にめんどくさいです。
やり方としてはhttpResponse.getBody()でresponseの本体が取れるので、JSON.deserializeUntyped()しつつMap<String, Object>にキャストしてあげると"result"キー、"info"キー以下の内容がList<Object>として扱えるようになります。

Map<String, Object> requestBody = (Map<String, Object>)JSON.deserializeUntyped(response.getBody());
// requestBody.keySet() : Set<String> => ('results', 'info')
// requestBody.get('results').values() : List<Object> => {'gender', 'name', 'location', ...}
// requestBody.get('info').values() : List<Object> => {'seed', 'results', 'page', 'version'}

"gender"やら"name"の値を扱うためには、List<Object>をループで回しながら、String.valueOf()で文字列に変換していくことになります。値がまた配列になっている場合はMap<String, Object>へのキャストというのをまたやってあげる必要があります。各階層について配列のキャストが必要になります。

Leadへのセット

ループのなかでinsertしないのが基本ですね。

感想

responseBodyはせめて文字列のMapとして扱えるようにしてほしいです。指定したsObjectに変換できるとかあればもっとありがたいですが。

14
Help us understand the problem. What is going on with this article?
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away

Comments

No comments
Sign up for free and join this conversation.
Sign Up
If you already have a Qiita account Login
14
Help us understand the problem. What is going on with this article?