LWCで外部APIを使ってみる

## 概要
LWCを勉強の一環として、外部APIを呼び出した結果をSalesforceの項目に反映させる方法を試してみました

### デモ
以下のように「郵便番号」項目を持つ取引先が存在するとします
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2640548/dd6078bb-b689-8dcc-508a-5290ac0d866b.png)

また、取引先を参照する「調査結果」オブジェクトがあって、この詳細画面にLWCで作った「住所情報反映」ボタンを設置しています
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2640548/5c52b940-6fa8-9fe8-3a79-4cd081ae1dcd.png)

ボタンを押下すると「住所」項目に取引先の郵便番号の住所が自動入力されます
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2640548/72b57947-cb78-435f-d171-4a38eef57065.png)

## 使用したAPI
zipcloudというサービスを利用しました

https://zipcloud.ibsnet.co.jp/doc/api

## 事前準備
上記サイトをリモートサイトの設定に登録する必要があります
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2640548/17aea7cf-86d8-1e71-2b17-48dfd8bfce26.png)

### 参照

https://help.salesforce.com/s/articleView?id=sf.configuring_remoteproxy.htm&type=5

## 実装内容
実装内容は以下の通りです
```searchPostalCodeAddress.html
<template>
    <lightning-button 
        variant="neutral"
        label="住所情報反映"
        onclick={getAddresInfoButton}
    ></lightning-button>
</template>
```
onclick={getAddresInfoButton}でクリックで動くJavascriptのメソッドを設定しています

```searchPostalCodeAddress.js
import { api, LightningElement,wire } from 'lwc';
import getAddress from '@salesforce/apex/ZipAddressController.getAddress';
import { ShowToastEvent } from 'lightning/platformShowToastEvent';
import { updateRecord } from 'lightning/uiRecordApi';
import ADDRESS_FIELD from '@salesforce/schema/SurveyResult__c.Address__c';
import ID_FIELD from '@salesforce/schema/SurveyResult__c.Id';

export default class SearchPostalCodeAddress extends LightningElement {
    @api recordId;

    getAddresInfoButton(event){
        getAddress({srId: this.recordId})
            .then(result => {
                const fields = {};
                fields[ID_FIELD.fieldApiName] = this.recordId;
                fields[ADDRESS_FIELD.fieldApiName] =
                    result.results[0].address1 +
                    result.results[0].address2 +
                    result.results[0].address3;
                const recordInput = { fields };
                
                updateRecord(recordInput)
                    .then(() => {
                        this.showSuccessToast('レコード作成成功', '取引先の住所情報が反映されました')
                    })
                    .catch(error => {
                        this.showErrorToast('Error', error.message);
                    });
                })
            .catch(error => {
                this.showErrorToast('Error', error.message);
            });
    }

    showErrorToast(title, message) {
        const evt = new ShowToastEvent({
            title: title,
            message: message,
            variant: 'error',
            mode: 'dismissable'
        });
        this.dispatchEvent(evt);
    }


    showSuccessToast(title, message) {
        const evt = new ShowToastEvent({
            title: title,
            message: message,
            variant: 'success',
            mode: 'sticky'
        });
        this.dispatchEvent(evt);
    }
}
```
ボタンのクリックによって、getAddresInfoButtonが起動するとApexのZipAddressControllerのgetAddressを呼び出します。返ってきた情報から住所の情報の文字列を結合して、項目を更新しています


```ZipAddressController.cls
public with sharing class ZipAddressController {

    @AuraEnabled(cacheable=true)
    public static Map<String, Object> getAddress(Id srId) {

        System.debug('start getAddress Class');
        List<SurveyResult__c> sr = new List<SurveyResult__c>();

        try{
            sr = [
                SELECT Id, Account__c, Account__r.PostalCode__c
                FROM SurveyResult__c
                WHERE Id = :srId
                WITH SECURITY_ENFORCED
                LIMIT 1
            ];
        } catch(System.QueryException e){
            throw new QueryException('This user dont have access right to ServeyResult object');
        }
            
        try {
            String zipcode = sr[0].Account__r.PostalCode__c;
            String endPoint = 'https://zipcloud.ibsnet.co.jp/api/search?zipcode=' + zipcode;
            HttpRequest request = new HttpRequest();
            request.setEndpoint(endPoint);
            request.setMethod('GET');
            request.setHeader('Content-Type','application/json');
            Http http = new Http();
            HttpResponse res = http.send(request);
            Map<String, Object> resultAdress = (Map<String, Object>) JSON.deserializeUntyped(res.getBody());
            return resultAdress;
        } catch (System.AuraHandledException e) {
            throw new AuraHandledException('Something went wrong: ' + e.getMessage());
        }

    }
}
```
詳細画面で開かれている「調査結果」レコードの情報を取得→紐づいている「取引先」の「郵便番号」を取得→zipcloudへGETリクエストの流れで住所の情報を取得しています

## 終わりに
普通は外部APIの接続には認証情報を定義したりする必要があると思いますし、今回の実装内容はフローでも実装可能です。LWCの勉強用に簡単に利用できるAPIを利用したのと、あえてLWCを使いました。ボタンの配置場所もビミョーでいけてないですが、流れは掴めたのでよしとしています。。