見出し画像

【完全保存版】Solana ActionsのGETとPOSTを学ぼう!

この記事は、下の「GET」「POST」部分を翻訳・編集したものです。

こちらの記事で、実際に作った後の方がイメージがつきやすいと思います。

1 リクエスト

アクションクライアントはまず、Action URLHTTP GET JSONリクエストを送信します。

このリクエストにはAccept-Encodingヘッダーを含める必要があります。

https://developer.medley.jp/entry/2021/02/01/180003

2 レスポンス

Action URLは、以下のボディペイロードを含むHTTP OK JSONレスポンス、またはHTTPエラーで応答する必要があります。

1 クライアントの処理

クライアントはHTTPクライアントエラー、サーバーエラー、およびリダイレクトレスポンスを処理する必要があります。

2 Content-Encodingヘッダーでの応答

エンドポイントはHTTP圧縮のためにContent-Encodingヘッダーで応答する必要があります。

https://developer.medley.jp/entry/2021/02/01/180003

3 キャッシュについて

クライアントは、HTTPキャッシングレスポンスヘッダーで指示されない限り、レスポンスをキャッシュしてはなりません。

4 レスポンスボディ情報の表示

クライアントは次に、アイコン、タイトル、説明、およびラベルなどのレスポンスボディ情報を表示する必要があります。

3 GETレスポンスボディ

HTTP OKステータスの成功したGETレスポンスは、以下のペイロードに準拠する必要があります。

1 icon

アクションを説明する画像絶対HTTPまたはHTTPS URLでなければなりません。

サポートされている画像フォーマットはSVG、PNG、またはWebPです。

これらのいずれでもない場合、クライアントはそれを不正な形式として拒否する必要があります。

2 title

アクションのタイトルを示すUTF-8文字列。

3 description

アクションの簡単な説明を提供するUTF-8文字列。

4 label

アクションを実行するために使用されるボタンに表示されるUTF-8文字列。

ラベルは5単語以内のフレーズに制限され、動詞で始まるべきです。例えば、「Mint NFT」、「Vote Yes」、「Stake 1 SOL」などです。

5 disabled

オプションのブール値。この値が存在する場合、アクションに関連するすべてのボタンは無効にされるべきです。

このオプションの値は省略可能であり、省略された場合はenabled=trueと同等です。

例えば、NFTコレクションが完売した場合や、投票期間が終了したガバナンス提案などで使用されることがあります。

6 error

オプションのエラー表示で、致命的ではないエラーを示し、人間が読める形式でエンドユーザーに表示されるべきです。

設定されている場合、クライアントがアクションを解釈したり表示したりするのを妨げるべきではありません。

例えば、ビジネスの制約、認可、状態、または外部リソースのエラーなどの理由を表示するために、disabledと一緒に使用することができます。

7 links.actions

このアクションに関連する追加のアクションのオプションの配列です。

各リンクされたアクションには、ボタンに表示されるラベルと関連するAction URL(href)が指定されます。

追加のアイコン、タイトル、説明は提供されません。

例えば、ガバナンスの投票アクションエンドポイントは、ユーザーに「Vote Yes」、「Vote No」、「Abstain from Vote(投票を控える)」の3つのオプションを返すことができます。

7ー1 links.actionが提供されない場合

リンクされたアクションが提供されない場合、クライアントはルートラベル文字列を使用して単一のボタンをレンダリングします。

そして、最初のGETリクエストと同じアクションURLエンドポイントPOSTリクエストを送信するべきです。

7ー2 links.actionが提供される場合

リンクされたアクションが提供される場合、クライアントはlinks.actionsフィールドにリストされている項目に基づいてボタンと入力フィールドのみをレンダリングするべきです。

クライアントはルートラベルの内容をボタンとしてレンダリングしてはなりません。

7ー3 ActionParametersについて

ActionParametersは、エンドユーザー向けのテキスト入力フィールドを含むアクションの第二のタイプを表します。

詳細については、アクションタイプを参照してください。

アクションがリンクされて複数アクションの体験を作成する方法については、マルチアクションを参照してください。

4 例

1 GETレスポンスの例

以下の例のレスポンスは、ユーザーに「Buy WIF」というラベルの単一のボタンを表示することを期待される単一の「ルート」アクションを提供します。

補足
links.actionがないパターンですね。

{
  "title": "Buy WIF with SOL",
  "icon": "<url-to-image>",
  "description": "Buy WIF using SOL. Choose a USD amount of SOL from the options below.",
  "label": "Buy WIF" // ボタンのテキスト
}

以下の例のレスポンスは、ユーザーに3つのボタンをクリックしてWIFを購入するための3つの関連アクションリンクを提供します。

補足
links.actionsが3つありますね。

{
  "title": "Buy WIF with SOL",
  "icon": "<url-to-image>",
  "description": "Buy WIF using SOL. Choose a USD amount of SOL from the options below.",
  "label": "Buy WIF",
  "links": {
    "actions": [
      {
        "label": "$10", // ボタンのテキスト
        "href": "/api/buy?amount=10"
      },
      {
        "label": "$100", // ボタンのテキスト
        "href": "/api/buy?amount=100"
      },
      {
        "label": "$1,000", // ボタンのテキスト
        "href": "/api/buy?amount=1000"
      }
    ]
  }
}

2 パラメータを含むGETレスポンスの例

以下の例のレスポンスは、ユーザーにWIFを購入するための3つのリンクアクションを提供します。

"$10"というラベルのボタン、"$100"というラベルのボタン、"$1,000"というラベルのボタン、および特定の"amount"値を入力するためのテキスト入力フィールド。

補足
最後のlinks.actionsにparametersがついていますね。

{
  "title": "Buy WIF with SOL",
  "icon": "<url-to-image>",
  "description": "Buy WIF using SOL. Choose a USD amount of SOL from the options below, or enter a custom amount.",
  "label": "Buy WIF", // `links.actions`が提供されているため表示されません
  "links": {
    "actions": [
      {
        "label": "$10", // ボタンのテキスト
        "href": "/api/buy?amount=10"
        // `parameters`がないためテキスト入力フィールドはありません
      },
      {
        "label": "$100", // ボタンのテキスト
        "href": "/api/buy?amount=100"
        // `parameters`がないためテキスト入力フィールドはありません
      },
      {
        "label": "$1,000", // ボタンのテキスト
        "href": "/api/buy?amount=1000"
        // `parameters`がないためテキスト入力フィールドはありません
      },
      {
        "label": "Buy WIF", // ボタンのテキスト
        "href": "/api/buy?amount={amount}",
        "parameters": [
          {
            "name": "amount", // フィールド名
            "label": "Enter a custom USD amount" // テキスト入力のプレースホルダー
          }
        ]
      }
    ]
  }
}

以下の例のレスポンスは、ユーザーが入力した金額がPOSTリクエストで送信される単一の入力フィールドを提供します。
(クエリパラメータまたはサブパスとして使用できます)

補足
links.actionsにparameters付きのものが一つですね。

{
  "icon": "<url-to-image>",
  "label": "Buy WIF",
  "title": "Buy WIF with SOL",
  "description": "Buy WIF using SOL. Choose a USD amount of SOL from the options below, or enter a custom amount.",
  "links": {
    "actions": [
      {
        "label": "Buy WIF", // ボタンのテキスト
        "href": "/api/buy/{amount}", // または /api/buy?amount={amount}
        "parameters": [
          // {amount}入力フィールド
          {
            "name": "amount", // 入力フィールド名
            "label": "Enter a custom USD amount" // テキスト入力のプレースホルダー
          }
        ]
      }
    ]
  }
}

5 POSTリクエスト

アクションは、次のボディペイロードを使用して、URLに対してHTTP POST JSONリクエストをサポートします。

{
  "account": "<account>"
}

ここで、accountはリクエストを行っているユーザーの公開鍵のbase58エンコードされた表現です。

クライアントはAccept-Encodingヘッダーを使用し、アクションサービスはHTTP圧縮のためにContent-Encodingヘッダーで応答する必要があります。

補足
この辺りはGETの時と同じですね。

6 POSTレスポンス

アクションサービスは、次の形式のペイロードを含むHTTP OK JSONレスポンスPOSTリクエストに応答する必要があります。

export interface ActionPostResponse {
  /** base64エンコードされたトランザクション */
  transaction: string;
  /** オプションのメッセージ、例えばトランザクションの性質を説明するために使用できます */
  message?: string;
}

クライアントはHTTPクライアントエラーサーバーエラー、およびリダイレクトレスポンスを処理する必要があります。

エンドポイントはapplication/jsonのContent-Typeヘッダーで応答する必要があります。

サポートをしていただけたらすごく嬉しいです😄 いただけたサポートを励みに、これからもコツコツ頑張っていきます😊