前提として、Salesforceの住所検索がコミュニティで対応していないので
GoogleMapAPIから郵便番号検索を行いたいと思います。
少し苦戦したのは、APIから受け取った情報を良い感じにサブクラスに割り当てるところです。
GoogleMapAPI.cls
@AuraEnabled
public static AddressInfo searchByPostalCode(String postalCode) {
// Google Maps API キー
String apiKey = 'ABCDEFG';
// Google Maps Geocoding API のエンドポイント URL を構築
String endpoint = 'END_POINT';
// パラメータを設定
String parameters = 'address=' + EncodingUtil.urlEncode(postalCode, 'UTF-8') + '&language=ja';
parameters += '&key=' + EncodingUtil.urlEncode(apiKey, 'UTF-8');
// HTTP リクエストを作成
HttpRequest request = new HttpRequest();
request.setEndpoint(endpoint + '?' + parameters);
request.setMethod('GET');
// HTTP リクエストを送信してレスポンスを取得
HttpResponse response = new Http().send(request);
// エラー時
if (response.getStatusCode() != 200) {
return null;
}
Map<String, Object> responseData = (Map<String, Object>) JSON.deserializeUntyped(response.getBody());
List<Object> results = (List<Object>) responseData.get('results');
AddressInfo addInfo = new AddressInfo();
if (results.isEmpty()) {
// 取得結果なしの場合
} else {
// 郵便番号に対応する結果が見つかった場合の処理
// ここの変換がめんどくさい
Map<String, Object> resultMap = (Map<String, Object>) results[0];
List<Object> addressComponents = (List<Object>) resultMap.get('address_components');
for (Object obj : addressComponents) {
Map<String, Object> objMap = (Map<String, Object>)obj;
// 住所タイプ
List<Object> types = (List<Object>)objMap.get('types');
// 都道府県、市区、町名のいずれかのString
String billingStr = (String)objMap.get('long_name');
if (types.contains('administrative_area_level_1')) {
// 都道府県
addInfo.billingState = billingStr;
} else if (types.contains('locality')) {
// 市区
addInfo.billingCity = billingStr;
} else if (types.contains('sublocality')) {
// 町名
addInfo.billingStreet = billingStr;
}
}
}
return addInfo;
}
// 画面表示情報のサブクラス
public class AddressInfo {
// 都道府県
@AuraEnabled public String billingState {get;set;}
// 市区
@AuraEnabled public String billingCity{get;set;}
// 町名
@AuraEnabled public String billingStreet {get;set;}
}
JSONの形はこんな感じ
GoogleMapAPI.JSON
"results" : [
{
"address_components" : [
{
"long_name" : "西新宿",
"short_name" : "西新宿",
"types" : [ "sublocality_level_1", "sublocality", "political" ]
},
{
"long_name" : "新宿区",
"short_name" : "新宿区",
"types" : [ "locality", "political" ]
},
{
"long_name" : "東京都",
"short_name" : "東京都",
"types" : [ "administrative_area_level_1", "political" ]
},
{
"long_name" : "日本",
"short_name" : "JP",
"types" : [ "country", "political" ]
}
],
厄介だったのは
・resultのさらに下にaddress_componentsがいること。
⇒result[0]を指定して、またListにキャストしないといけない...
・typeだけ配列になっていること。
⇒typeだけのListを取得して、containsで比較している。
typeの中身が1つなら、equalsで比較できたのにな。
そもそもApexを介す必要はないんだけど
APIキーとか、その辺を直書きしたくないとか
jsにゴリゴリコーディングしたくない
みたいな感じでApexで書いてみました。
ApexのObject型は、なんかしっくりこないな~