【salesforce】ApexでのJSON処理はJSON2Apexに任せよう

今回はsalesforceでApexで外部APIコールアウト時に、レスポンスのjsonを処理する際に便利なJSON2Apexについて紹介します。

最近インターン先で会社のsalesforce構築の手伝いを行っています。

就職先でもsalesforceは扱っており、必要な経験になりそうなので、いまのうちに経験させてくれるインターン先には感謝です。学生時代の大半は飲食店のバイトで過ごしてきましたが、飲食店とインターンを掛け持ちするのが一番成長できる環境になってたかもしれないと後悔です。

salesforceといえば、無料で簡単にデプロイできるHerokuにすごいお世話になっております。しかし、自分の知っているHerokuより広い世界がsalesforceにはありました。できることが多くて、わからないことだらけ。それでかつ使いやすいようにプロセスを整理しないといけない…

構築して使ってもらって「使いやすくていいね!」と言われるまで頑張ります。

今回はsalesforceのApexで、外部APIコールのレスポンス処理に便利なJSON2Apexについて紹介します。

salesforceとは

salesforceとは、セールスフォース・ドットコム社が提供する世界で一番利用されているCRM(顧客管理)とSFA(営業支援)のアプリケーションです。すなわち、顧客情報の管理とその顧客に対する営業のプロセスを手伝うアプリケーションにです。

特徴は、SaaS型のクラウドサービスなので、ハードの保守やセキュリティを気にすることなく、サービスを利用することに注力できる点です。

成功事例には名前の聞いたことある会社から、ローカルですごく有名な会社まで様々です。

似たようなサービスに下の記事でも紹介したサイボウズのkintoneがありますが、違いとしてはkintoneよりsalesforceのほうができる範囲が広いというイメージがあります。

【kintone×Microsoft teams】kintoneのコメントをteamsに通知する
今回は、kintoneのレコードにコメントが追加された際にteamsに通知をしたい、という提案を受けて簡単にGASを仲介してkintoneのコメントをteamsへの通知を実装しました。

できる範囲が広いということは、メリットに思えますが、どう整理して何をしたらいいかわからないというデメリットにもなります。

今回はインターン先でsalesforceを構築するにあたって、サポートとして入ることになりました。その際に外部APIをコールした際にレスポンスのjson処理が便利になるツールJSON2Apexを紹介します。

salesforceでの外部APIコール

salesforceでの外部APIコールはどいうことかと思う人もいるかもしれません。今回「SNS広告(Facebook)の広告データをレコードとして自動で保存できないか?」というアイデアがあったので、Facebook APIをコールして、レコードとして保存する処理をApexで実装しました。

その際にAPIをコールした後のレスポンスのjson処理に戸惑ったので、レスポンスのjson処理が簡単になるツールを紹介します。

もちろんデフォルトの機能やiPaaS (Integration Platform as a Service :zapierintegromatなど)を利用すれば、簡単に接続できたかもしれませんが、ライセンスの関係や料金の関係などでApexを使って、勉強がてら実装することにしました。

Apexとは

Apexとは、Javaに似ているSalesforceの機能を拡張する際に使われるオブジェクト指向のプログラミング言語です。レコードのCRUD処理や、標準で用意されているアクションとは違った、カスタマイズしたアクションを実装することができます。

一番簡単な例でいくと、レコードの詳細をteamsに共有したい時などに処理を行うボタンを作成して、レコード詳細ページに配置するなどです。

ちなみに私はApexについては全くの初心者で、Apexに似ているJavaも勉強程度しか触っておらず、なんとなく調べればわかる初心者です。

レスポンスの処理

Apexでのjson処理は、以下の2つの方法があります。

①クラスを定義して、一発で処理
②Mapを使ってそれぞれ処理

レスポンスのjsonのパターンにもよりますが、下のようなネストのないjsonは②の方法で十分だと思います。

{
  "id":1,
  "name":"okinawa",
  "color":"red"
},....

しかし、以下のようなネストのあるjsonだと複雑です。今回はFacebook insights APIのレスポンスを紹介します。

{
   "data": [
   {
     "clicks": "100",
     "spend": "987",
     "impressions": "1221",
     "objective": "EVENT_RESPONSES",
     "ctr": "0.5342",
     "date_start": "2019-09-22",
     "date_stop": "2019-10-28"
   }
  ],
  "paging": {
    "cursors": {
      "before": "MAZDZD",
      "after": "MAZDZD"
    }
  }
}

このようなjsonだと②の方法でやるのは難しく、また①の方法ではApexクラスを用意する必要があるためApex初心者であると難しいです。

そこで①の方法で使うApexクラスをボタン一つで作成する、JSON2Apexを紹介します。

JSON2Apex

salesforceの学習プラットホームであるtrailheadの「API REST コールアウト」でも紹介されているツールです。

手順は簡単です。まず、JSON2Apexにアクセスします。

JSON2Apexチュートリアル

①に処理したいjsonを入力、②に適当に名前をつけます。そして③をクリックするとApexクラスとテストコードが入ったzipファイルがダウンロードされます。ダウンロードしたApexクラスの中身は以下のようになっています。例として上で紹介したFacebook insights APIのレスポンスに対する出力されたApexクラスです。

//
// Generated by JSON2Apexhttp://json2apex.herokuapp.com/
//

public class JSON2Apex {

  public List<Data> data;
  public Paging paging;

  public class Paging {
    public Cursors cursors;
  }

  public class Cursors {
   public String before;
   public String after;
  }

  public class Data {
    public String spend;
    public String impressions;
    public String objective;
    public String ctr;
    public String date_start;
    public String date_stop;
  } 
  public static JSON2Apex parse(String json) {
    return (JSON2Apex) System.JSON.deserialize(json, JSON2Apex.class);
  }
}

これを定義して、例えばctrを小数として取り出したい場合、以下のようにして取り出すことが可能になります。

//外部WebサービスのAPIをコールする
Srting EndPoint='APIのエンドポイント';
Http http = new Http();
HttpRequest request_data = new HttpRequest();
request_data.setEndpoint(Endpoint);
request_data.setMethod('GET');
HttpResponse response_data = http.send('request_data');

//受け取ったレスポンスをstr型にして、準備しておいたJSON2Apexでパースする。(=使いやすいようにする)
String data_str = response_data.getbody();
JSON2Apex InsightData = JSON2Apex.parse(data_str);

//ctrはstringで返されるので小数にする
Decimal ctr = decimal.valueOf(InsightData.Data[0].ctr);

“Inner types are not allowed to have inner types”エラーについて

JSON2Apexで出力されたApexクラスをそのまま使用してもエラーが出る場合があります。実際私の場合も「Inner types are not allowed to have inner types”」のエラーがでました。日本語にすると、「内部型は、内部型を持つことができない」とのことです。なとんなく括弧の位置がおかしいのかなと感じます。

予想通りこのエラーの解決方法は、ここの質問に解決策が示されています。出力されたApexクラスを少しいじります。

//
// Generated by JSON2Apexhttp://json2apex.herokuapp.com/
//

public class JSON2Apex {

  public List<Data> data;
  public Paging paging;

  public class Paging {
    public Cursors cursors;
  }

  public class Cursors {
   public String before;
   public String after;
  }

  public class Data {
    public String spend;
    public String impressions;
    public String objective;
    public String ctr;
    public String date_start;
    public String date_stop;
  } 
  public static JSON2Apex parse(String json) {
    return (JSON2Apex) System.JSON.deserialize(json, JSON2Apex.class);
  }
}

このように出力されたApexクラスの赤文字で示す括弧の位置を移動します。そうすると”Inner types are not allowed to have inner types”エラーは解決します。

//
// Generated by JSON2Apexhttp://json2apex.herokuapp.com/
//

public class JSON2Apex {
  public List<Data> data;
  public Paging paging;
}//ここに移動する

 public class Paging {
   public Cursors cursors;
 }

public class Cursors {
  public String before;
  public String after;
}

public class Data {
   public String spend;
   public String impressions;
   public String objective;
   public String ctr;
   public String date_start;
   public String date_stop;
 }
 
 public static JSON2Apex parse(String json) {
   return (JSON2Apex) System.JSON.deserialize(json, JSON2Apex.class);
 }
//}・・・ここの括弧を上の位置に移動

まとめ

salesforceでApexで外部APIコールアウト時に、レスポンスのjsonを処理する際に便利なJSON2Apexについて紹介しました。外部APIコールアウトして、レコードに追加したいと考えている方の参考になればうれしいです。
よくわからない点、相談があればにお願いします。

コメント

タイトルとURLをコピーしました