指定ログイン情報をつかったApexコールアウトを試してみました。Salesforce World Tour TokyoのMini HackのApexのチャレンジで指定ログインを使用するものがありました。指定ログインは使ったことなかったので勉強してみようかとさわってみました。
指定ログインの使い方についてはヘルプサイトにまとめられています。
・・・ですが、よくわかっていない機能をテキストのみで理解するのはちょっとしんどい。ということでYoutube動画の方で勉強しました。(こちらもちょっとUIが変わっていたりと情報が古くなっていましたが)
指定ログインの設定
設定メニューで「指定ログイン」と検索して設定ページにアクセスします。
最初にやるのは外部ログイン情報タブを選択して、新規ボタンをクリックすることです。
このようなポップアップが表示されます。
入力イメージです。表示ラベルと名前は任意ですが、名前の方はApexコード内で記述する場面があります。(API名的な使い方)
これで外部ログイン情報の枠ができました。
作成後に表示された画面にプリンシパルというエリアが用意されています。次はここで新規ボタンをクリックします。
このような感じで認証パラメータを設定する箇所となっています。今回はユーザIDとパスワードをパラメータとして渡したいので設定します。パラメータ名はおそらく表示ラベル的な感じで区別するぐらいの使い方です。パラメータの名前の方はAPI的な感じで他で参照されます。
登録結果。
次にプリンシバルの下にあるカスタムヘッダーを登録します。入力イメージは次のような感じ。
画面キャプチャ内の値の内容です。
{!'Basic '& BASE64ENCODE(BLOB($Credential.BasicAuth.Username &':'& $Credential.BasicAuth.Password))}
$Credentialが指定ログインのグローバル変数です。
BasicAuthは最初に登録した外部ログイン情報のAPI名になります。
そのあとのUsernameとPasswordはプリンシパルに登録した値の変数名となります。
これで外部ログイン情報の登録がほぼ完了です。
次に指定ログインの最初のページに戻って指定ログイン情報を登録します。新規ボタンをクリックします。
入力イメージです。
URLはAPI実行する先のエンドポイントです。外部ログイン情報は先程登録したものを選択します。コールアウトオプションはYoutube動画を参考にしました。
これで指定ログイン情報タブの登録作業は完了です。
設定の最後に権限セットを用意する必要があります。この指定ログイン情報を使ってAPI実行できるユーザは権限セットで指定します。
枠の作成は特別なことは特に無し。
権限セットができたら外部ログイン情報プリンシパルアクセスを選択します。
さきほど作成したプリンシバルを有効化します。
これで権限セットの作成は完了です。できたものをユーザに割り当てます。
以上で指定ログインの設定が完了となります。
指定ログインをつかったApexコールアウト処理の書き方
コールアウト処理はHttpRequestの処理をつかってsetEndpointなどを指定しながら処理を実装しますが、指定ログインの場合はsetEndpointの書き方が変わります。
次のように『callout:Basic_Apex_Callout』という書き方です。URLやリクエストパラメータは指定ログイン情報側で保持しているので、Apex側で宣言する必要はありません。これだけで
request.setEndpoint('callout:Basic_Apex_Callout');
デバッグ処理を追加して動作確認します。
このようにステータスコード=200となり、API実行結果を取得できました。
指定ログインのApexクラスでの使い方はこんな感じです。
リモートサイトの設定について
今回のように外部システムのAPIを実行する場合はリモートサイトの設定を行い、対象の外部サイトを許可する必要があります。ですが、指定ログイン情報の設定を使用する場合はそちらで許可設定まで行ってくれるのでリモートサイトの設定は不要となります。今回の動作確認でも特に追加設定等は行っていない状態で動作できました。
おまけ
指定ログインの使い方は以上となりますが、さいごにちょっとおまけです。今回試したきっかけはSalesforce World TourのMiniHackチャレンジでした。MiniHackの方は指定ログインの設定で終わりではなく、その結果を用意したオブジェクトに登録するところまでとなっていました。
APIの実行結果はJSON形式 (String型)で返ってきます。そうした結果を処理で使えるようにするにはObject型に変換する感じとなります。
今回は単純なリスト形式なので次のような感じ。
// 実行結果をリスト型に変換 List<Object> results = (List<Object>)JSON.deserializeUntyped(response.getBody()); // 取得したリスト件数分処理 for (Object result : results) { // マップ型に変換 (マップのキーはAPI戻り値のキーとなります。) Map<String, Object> resultMap = (Map<String, Object>)result; // マップ型に変換後は次のような感じで値を取得できる。 System.debug((String)resultMap.get('food-category')); }
単純なリストじゃない場合は次のような受け取り方もあります。とりあえず『JSON.deserializeUntyped』とObject型というので対応できると思います。
Map<String, Object> resultMap = (Map<String, Object>)JSON.deserializeUntyped(response.getBody());
お役立ちリソース
- ドキュメント: 指定ログイン情報
- ドキュメント: 指定ログイン情報の数式関数
- Developer Blog: Announcing the Next Generation of Named Credentials
- 動画(Youtube): Apex: Basic REST Callouts
- 動画(Youtube): How to Invoke Apex from Flows Using InvocableMethod Annotation
- Trailhead: Distribute the Flow with a Custom Button