標準メソッド

この章では、ListGetCreateUpdateDelete といった標準メソッドのコンセプトを定義します。標準メソッドを使用すると、複雑性が軽減され、整合性が強化されます。Google API リポジトリ内の 70% を超える API が標準メソッドであり、容易に学習して使用できるようになっています。

次の表に、標準メソッドと HTTP メソッドとのマッピングを示します。

標準メソッド HTTP マッピング HTTP リクエスト本文 HTTP レスポンス本文
List GET <collection URL> なし リソース*リスト
Get GET <resource URL> なし リソース*
Create POST <collection URL> リソース リソース*
Update PUT or PATCH <resource URL> リソース リソース*
Delete DELETE <resource URL> なし google.protobuf.Empty**

*返されるフィールドのサブセットを指定するレスポンス フィールド マスクをサポートするメソッドの場合、ListGetCreateUpdate メソッドから返されるリソースに、部分データが含まれる可能性があります。場合によっては、API プラットフォームでは、すべてのメソッドについてフィールド マスクがネイティブにサポートされます。

**リソースをすぐに削除しない Delete メソッド(フラグの更新や長時間実行される削除オペレーションの作成など)から返されるレスポンスには、長時間実行オペレーションか変更されたリソースのいずれかを含めることが推奨されます。

標準メソッドでは、1 回の API 呼び出しの期間内で完了しないリクエストに対しても、長時間実行オペレーションが返される可能性があります。

以降では、各標準メソッドについて詳しく説明します。 これらの例は、HTTP マッピングのための特殊なアノテーションを含む .proto ファイルで定義されたメソッドを示しています。標準メソッドを使用するその他の例については、Google API リポジトリを参照してください。

リスト

List メソッドは、コレクション名と 0 個以上のパラメータを入力として受け取り、入力に一致するリソースのリストを返します。

List は、リソースの検索によく使用されます。List は、サイズに制限がありキャッシュに保存されていない単一のコレクションのデータに適しています。より範囲が広い場合は、カスタム メソッド Search を使用することが推奨されます。

バッチ取得(複数のリソース ID を取得し、それらの各 ID についてオブジェクトを返すメソッドなど)は、List ではなく、カスタム BatchGet メソッド として実装することが奨励されます。ただし、同じ機能を提供する既存の List メソッドがある場合は、この目的のために、代わりに List メソッドを再利用できます。カスタム BatchGet メソッドを使用する場合は、このメソッドを HTTP GET にマッピングすることが推奨されます。

適用可能な一般的なパターン: ページ分割結果の順序付け

適用可能な命名規則: フィルタ フィールド結果フィールド

HTTP マッピング:

  • List メソッドでは、HTTP GET 動詞を使用する必要があります
  • リソースがリストされているコレクションの名前を受け取るリクエスト メッセージ フィールドは、URL パスにマッピングすることが推奨されます。コレクション名を URL パスにマッピングする場合、URL テンプレートの最後のセグメント(コレクション ID)は、リテラルであることが必須です。
  • 残りのリクエスト メッセージ フィールドはすべて、URL クエリ パラメータにマッピングすべきです。
  • リクエスト本文は存在しません。API 構成で body 句を宣言することはできません
  • レスポンス本文には、リソースのリストと任意のメタデータを含めることが推奨されます。

例:

// Lists books in a shelf.
rpc ListBooks(ListBooksRequest) returns (ListBooksResponse) {
  // List method maps to HTTP GET.
  option (google.api.http) = {
    // The `parent` captures the parent resource name, such as "shelves/shelf1".
    get: "/v1/{parent=shelves/*}/books"
  };
}

message ListBooksRequest {
  // The parent resource name, for example, "shelves/shelf1".
  string parent = 1;

  // The maximum number of items to return.
  int32 page_size = 2;

  // The next_page_token value returned from a previous List request, if any.
  string page_token = 3;
}

message ListBooksResponse {
  // The field name should match the noun "books" in the method name.  There
  // will be a maximum number of items returned based on the page_size field
  // in the request.
  repeated Book books = 1;

  // Token to retrieve the next page of results, or empty if there are no
  // more results in the list.
  string next_page_token = 2;
}

取得

Get メソッドは、リソース名、0 個以上のパラメータを取得し、指定されたリソースを返します。

HTTP マッピング:

  • Get メソッドでは、HTTP GET 動詞を使用する必要があります
  • リソース名を受け取るリクエスト メッセージ フィールドは、URL パスにマッピングすることが推奨されます。
  • 残りのリクエスト メッセージ フィールドはすべて、URL クエリ パラメータにマッピングすべきです。
  • リクエスト本文は存在しません。API 構成で body 句を宣言することはできません
  • 返されるリソースは、レスポンス本文全体にマッピングされます

例:

// Gets a book.
rpc GetBook(GetBookRequest) returns (Book) {
  // Get maps to HTTP GET. Resource name is mapped to the URL. No body.
  option (google.api.http) = {
    // Note the URL template variable which captures the multi-segment resource
    // name of the requested book, such as "shelves/shelf1/books/book2"
    get: "/v1/{name=shelves/*/books/*}"
  };
}

message GetBookRequest {
  // The field will contain name of the resource requested, for example:
  // "shelves/shelf1/books/book2"
  string name = 1;
}

作成

Create メソッドは、親リソース名、リソース、および 0 個以上のパラメータを取得します。これにより、指定された親の下に新しいリソースが作成され、新たに作成されたリソースが返されます。

API がリソースの作成をサポートしている場合は、作成可能なリソースのタイプごとに Create メソッドを含めることが推奨されます。

HTTP マッピング:

  • Create メソッドでは、HTTP POST 動詞を使用する必要があります
  • リクエスト メッセージには、リソースが作成される親リソース名を指定するフィールド parent を含めることが推奨されます。
  • リソースを含むリクエスト メッセージ フィールドは、HTTP リクエスト本文にマッピングされていることが必須となります。Create メソッドに google.api.http アノテーションを使用する場合は、body: "<resource_field>" フォームを使用することが必須です。
  • リクエストには、<resource>_id という名前のフィールドを含めることができます。これにより、呼び出し元はクライアントに割り当てられた ID を選択できるようになります。このフィールドはリソース内に含めることができます
  • 残りのリクエスト メッセージ フィールドはすべて、URL クエリ パラメータにマッピングすべきです。
  • 返されるリソースは、HTTP レスポンス本文全体にマッピングすべきです。

クライアントによって割り当てられたリソース名が Create メソッドでサポートされており、そのリソースがすでに存在する場合、リクエストはエラーコード ALREADY_EXISTS で失敗するか、サーバーによって割り当てられた別のリソース名が使用される必要があります。ドキュメントでは、作成されたリソース名は、渡されたものとは異なる可能性があることを明確にする必要があります。

リソース スキーマが変更されたときに、リクエスト スキーマとリソーススキーマの両方を更新する必要がないようにするには、Create メソッドで入力リソースを取得することが必須となります。クライアントが設定できないリソース フィールドについては、「出力専用」フィールドとして文書化する必要があります。

例:

// Creates a book in a shelf.
rpc CreateBook(CreateBookRequest) returns (Book) {
  // Create maps to HTTP POST. URL path as the collection name.
  // HTTP request body contains the resource.
  option (google.api.http) = {
    // The `parent` captures the parent resource name, such as "shelves/1".
    post: "/v1/{parent=shelves/*}/books"
    body: "book"
  };
}

message CreateBookRequest {
  // The parent resource name where the book is to be created.
  string parent = 1;

  // The book id to use for this book.
  string book_id = 3;

  // The book resource to create.
  // The field name should match the Noun in the method name.
  Book book = 2;
}

rpc CreateShelf(CreateShelfRequest) returns (Shelf) {
  option (google.api.http) = {
    post: "/v1/shelves"
    body: "shelf"
  };
}

message CreateShelfRequest {
  Shelf shelf = 1;
}

更新

Update メソッドは、リソースと 0 個以上のパラメータを含むリクエスト メッセージを取得します。指定されたリソースとそのプロパティを更新し、更新されたリソースを返します。

変更可能なリソース プロパティは、リソースの名前または親を含むプロパティを除き、Update メソッドで変更可能にする必要があります。リソースの名前を変更や移動を行う機能はいずれも、Update メソッドでは使用できません。代わりに、カスタム メソッドによって処理することが推奨されます。

HTTP マッピング:

  • 標準の Update メソッドでは、部分的なリソース更新をサポートし、update_mask という名前の FieldMask フィールドで HTTP 動詞 PATCH を使用する必要があります。入力としてクライアントから提供されている出力フィールドは無視する必要があります。
  • 繰り返しフィールドへの追加など、より高度なパッチ適用セマンティクスを必要とする Update メソッドを、カスタム メソッドで使用できるようにする必要があります。
  • Update メソッドで完全なリソース更新のみがサポートされている場合は、HTTP 動詞 PUT を使用することが必須となります。ただし、完全な更新は、新しいリソース フィールドを追加するときに下位互換性に関する問題が生じるため、推奨されません。
  • リソース名を受け取るメッセージ フィールドは、URL パスにマッピングすることが必須となります。このフィールドは、リソース メッセージ自体に含めることができます
  • リソースを含むリクエスト メッセージ フィールドは、リクエスト本文にマッピングされていることが必須となります。
  • 残りのリクエスト メッセージ フィールドはすべて、URL クエリ パラメータにマッピングされていることが必須となります。
  • レスポンス メッセージは、更新されたリソース自体であることが必須となります。

API でクライアントによって割り当てられたリソース名が許容される場合、サーバーでは、クライアントにより存在しないリソース名を指定して、新しいリソースを作成できます。 それ以外の場合、Update メソッドは、リソース名が存在しないという理由で失敗します。 これが唯一のエラー条件であるなら、エラーコード NOT_FOUND が使用されます。

リソースの作成をサポートする Update メソッドを含む API では、Createメソッドも提供することが推奨されます。この理由は、リソースを作成する方法が Update メソッドのみである場合、リソースの作成方法が不明確になるためです。

例:

// Updates a book.
rpc UpdateBook(UpdateBookRequest) returns (Book) {
  // Update maps to HTTP PATCH. Resource name is mapped to a URL path.
  // Resource is contained in the HTTP request body.
  option (google.api.http) = {
    // Note the URL template variable which captures the resource name of the
    // book to update.
    patch: "/v1/{book.name=shelves/*/books/*}"
    body: "book"
  };
}

message UpdateBookRequest {
  // The book resource which replaces the resource on the server.
  Book book = 1;

  // The update mask applies to the resource. For the `FieldMask` definition,
  // see https://developers.google.com/protocol-buffers/docs/reference/google.protobuf#fieldmask
  FieldMask update_mask = 2;
}

削除

Delete メソッドは、リソース名と 0 個以上のパラメータを取得し、指定されたリソースを削除するか、削除をスケジュールします。Delete メソッドは、google.protobuf.Empty を返すようにします。

Delete メソッドを繰り返し呼び出すことはできないため、このメソッドから返される情報に API は依存しないようにすることが推奨されます。

HTTP マッピング:

  • Delete メソッドでは、HTTP DELETE 動詞を使用する必要があります
  • リソース名を受け取るリクエスト メッセージ フィールドは、URL パスにマッピングすることが推奨されます。
  • 残りのリクエスト メッセージ フィールドはすべて、URL クエリ パラメータにマッピングすべきです。
  • リクエスト本文は存在しません。API 構成で body 句を宣言することはできません
  • Delete メソッドがすぐにリソースを削除する場合は、空のレスポンスを返すことが推奨されます。
  • Delete メソッドが長時間実行オペレーションを開始する場合は、長時間実行オペレーションが返すことが推奨があります。
  • Delete メソッドが削除済みとしてリソースをマークするのみの場合は、更新されたリソースを返すことが推奨されます。

Delete メソッドの呼び出しは、実際にはべき等である必要がありますが、同じレスポンスを返す必要はありません。Delete リクエストの回数に関係なく、最終的にリソースが削除される必要がありますが、最初のリクエストのみが成功コードになります。それ以降のリクエストは、google.rpc.Code.NOT_FOUND になります。

例:

// Deletes a book.
rpc DeleteBook(DeleteBookRequest) returns (google.protobuf.Empty) {
  // Delete maps to HTTP DELETE. Resource name maps to the URL path.
  // There is no request body.
  option (google.api.http) = {
    // Note the URL template variable capturing the multi-segment name of the
    // book resource to be deleted, such as "shelves/shelf1/books/book2"
    delete: "/v1/{name=shelves/*/books/*}"
  };
}

message DeleteBookRequest {
  // The resource name of the book to be deleted, for example:
  // "shelves/shelf1/books/book2"
  string name = 1;
}