Méthodes standards

Ce chapitre définit le concept des méthodes standards, à savoir List, Get, Create, Update et Delete. Les méthodes standards réduisent la complexité et augmentent la cohérence. Plus de 70 % des méthodes API du dépôt des API Google sont des méthodes standards, ce qui les rend beaucoup plus faciles à apprendre et à utiliser.

Le tableau suivant explique comment mapper des méthodes standards à des méthodes HTTP :

Méthode standard Mappage HTTP Corps de la requête HTTP Corps de la réponse HTTP
List GET <collection URL> N/A Liste de ressources*
Get GET <resource URL> N/A Ressource*
Create POST <collection URL> Ressource Ressource*
Update PUT or PATCH <resource URL> Ressource Ressource*
Delete DELETE <resource URL> N/A google.protobuf.Empty**

*La ressource renvoyée par les méthodes List, Get, Create et Update peut contenir des données partielles si elles acceptent les masques de champs de réponse, qui spécifient un sous-ensemble de champs à renvoyer. Dans certains cas, la plate-forme API est compatible de manière native avec les masques de champ de toutes les méthodes.

**La réponse renvoyée par une méthode Delete qui ne supprime pas immédiatement la ressource (telle que la mise à jour d'un indicateur ou la création d'une opération de suppression de longue durée) devrait contenir l'opération de longue durée ou la ressource modifiée.

Une méthode standard peut également renvoyer une opération de longue durée pour les requêtes qui ne se terminent pas dans le délai imparti pour un appel d'API unique.

Les sections suivantes décrivent chacune des méthodes standards en détail. Les exemples montrent les méthodes définies dans les fichiers .proto avec des annotations spéciales pour les mappages HTTP. Vous trouverez de nombreux exemples utilisant des méthodes standards dans le dépôt des API Google.

Liste

La méthode List prend un nom de collection et zéro ou plusieurs paramètres en tant qu'entrée et renvoie une liste de ressources correspondant à l'entrée.

La méthode List est couramment utilisée pour rechercher des ressources. List convient aux données d'une seule collection dont la taille est limitée et non mise en cache. Pour des cas plus vastes, la méthode personnalisée Search devrait être utilisée.

Une méthode Get par lots (telle qu'une méthode qui prend plusieurs ID de ressources et renvoie un objet pour chacun de ces ID) devrait être implémentée en tant que méthode BatchGet personnalisée, plutôt qu'en tant que méthode List. Toutefois, si vous possédez déjà une méthode List existante qui fournit les mêmes fonctionnalités, vous pouvez réutiliser la méthode List à cet effet à la place. Si vous utilisez une méthode BatchGet personnalisée, celle-ci devrait être mappée sur HTTP GET.

Schémas communs applicables : pagination, classement des résultats

Conventions d'attribution de noms applicables : champ filtre, champ résultats

Mappage HTTP :

  • La méthode List doit utiliser un verbe HTTP GET.
  • Le ou les champs de message de requête recevant le nom de la collection dont les ressources sont répertoriées devraient mapper vers le chemin de l'URL. Si le nom de la collection correspond au chemin de l'URL, le dernier segment du modèle d'URL (l'ID de la collection) doit être littéral.
  • Tous les champs de message de requête restants devront mapper vers les paramètres de requête d'URL.
  • S'il n'y a pas de corps de requête, la configuration de l'API ne doit pas déclarer de clause body.
  • Le corps de la réponse devrait contenir une liste de ressources ainsi que des métadonnées facultatives.

Exemple :

// 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

La méthode Get prend un nom de ressource, zéro ou plusieurs paramètres et renvoie la ressource spécifiée.

Mappage HTTP :

  • La méthode Get doit utiliser un verbe HTTP GET.
  • Le ou les champs de message de requête recevant le nom de la ressource devraient mapper vers le chemin de l'URL.
  • Tous les champs de message de requête restants devront mapper vers les paramètres de requête d'URL.
  • S'il n'y a pas de corps de requête, la configuration de l'API ne doit pas déclarer de clause body.
  • La ressource renvoyée devra mapper vers l'ensemble du corps de la réponse.

Exemple :

// 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

La méthode Create prend un nom de ressource parent, une ressource et zéro ou plusieurs paramètres. Elle crée une ressource sous le parent spécifié et renvoie la ressource nouvellement créée.

Si une API est compatible avec la création de ressources, elle devrait avoir une méthode Create pour chaque type de ressource pouvant être créée.

Mappage HTTP :

  • La méthode Create doit utiliser un verbe HTTP POST.
  • Le message de la requête devrait contenir un champ parent qui spécifie le nom de la ressource parente sur laquelle créer la ressource.
  • Le champ du message de requête contenant la ressource doit mapper vers le corps de la requête HTTP. Si l'annotation google.api.http est utilisée pour la méthode Create, le formulaire body: "<resource_field>" doit être utilisé.
  • La requête peut contenir un champ nommé <resource>_id pour permettre aux appelants de sélectionner un identifiant attribué par le client. Ce champ peut se trouver à l'intérieur de la ressource.
  • Tous les champs de message de requête restants devront mapper vers les paramètres de requête d'URL.
  • La ressource renvoyée devra mapper vers l'ensemble du corps de la réponse HTTP.

Si la méthode Create accepte le nom de ressource attribué par le client et que celle-ci existe déjà, la requête devrait échouer avec le code d'erreur ALREADY_EXISTS ou utiliser un nom de ressource attribué par un autre serveur. Veillez à ce que la documentation stipule clairement que le nom de la ressource créée peut être différent de celui qui a été renseigné.

La méthode Create doit utiliser une ressource d'entrée. Ainsi, lorsque le schéma de la ressource est modifié, il n'est pas nécessaire de mettre à jour le schéma de requête et le schéma de ressource. Pour les champs de ressource qui ne peuvent pas être définis par les clients, ils doivent être documentés sous la forme de champs de "sortie uniquement".

Exemple :

// 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

La méthode Update prend un message de requête contenant une ressource et zéro ou plusieurs paramètres. Elle met à jour la ressource spécifiée et ses propriétés, puis renvoie la ressource mise à jour.

Les propriétés de la ressource modifiable devraient être modifiables par la méthode Update, à l'exception des propriétés contenant le nom ou le parent de la ressource. Toute fonctionnalité permettant de renommer ou de déplacer une ressource ne doit pas exister dans la méthode Update. Elle devra plutôt être gérée par une méthode personnalisée.

Mappage HTTP :

  • La méthode Update standard devrait accepter la mise à jour partielle des ressources et utiliser le verbe HTTP PATCH avec un champ FieldMask nommé update_mask. Les champs de sortie fournis par le client en tant qu'entrées devraient être ignorés.
  • Une méthode Update nécessitant une sémantique de correctif plus avancée, telle que l'ajout d'un champ répété, devrait être rendue disponible par une méthode personnalisée.
  • Si la méthode Update ne permet que la mise à jour complète des ressources, elle doit utiliser le verbe HTTP PUT. Cependant, la mise à jour complète est fortement déconseillée, car elle pose des problèmes de rétrocompatibilité lors de l'ajout de nouveaux champs de ressources.
  • Le champ de message recevant le nom de la ressource doit mapper vers le chemin de l'URL. Le champ peut se trouver dans le message de ressource lui-même.
  • Le champ du message de requête contenant la ressource doit mapper vers le corps de la requête.
  • Tous les champs de message de requête restants doivent mapper vers les paramètres de requête d'URL.
  • Le message de réponse doit être la ressource mise à jour elle-même.

Si l'API accepte les noms de ressources attribués par le client, le serveur peut autoriser le client à spécifier un nom de ressource inexistant et à créer une nouvelle ressource. Sinon, la méthode Update devrait échouer avec un nom de ressource inexistant. Le code d'erreur NOT_FOUND devrait être utilisé s'il s'agit de la seule condition d'erreur.

Une API avec une méthode Update qui accepte la création de ressources devrait également fournir une méthode Create. Cela s'explique par le fait qu'il n'est pas évident de savoir créer des ressources si seule la méthode Update est disponible.

Exemple :

// 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

La méthode Delete prend un nom de ressource et zéro ou plusieurs paramètres, et supprime ou planifie la suppression de la ressource spécifiée. La méthode Delete devrait renvoyer google.protobuf.Empty.

Une API ne devrait pas s'appuyer sur des informations renvoyées par une méthode Delete, car elle ne peut pas être invoquée à plusieurs reprises.

Mappage HTTP :

  • La méthode Delete doit utiliser un verbe HTTP DELETE.
  • Le ou les champs de message de requête recevant le nom de la ressource devraient mapper vers le chemin de l'URL.
  • Tous les champs de message de requête restants devront mapper vers les paramètres de requête d'URL.
  • S'il n'y a pas de corps de requête, la configuration de l'API ne doit pas déclarer de clause body.
  • Si la méthode Delete supprime immédiatement la ressource, elle devrait renvoyer une réponse vide.
  • Si la méthode Delete lance une opération de longue durée, elle devrait renvoyer l'opération de longue durée.
  • Si la méthode Delete marque uniquement la ressource comme étant en cours de suppression, elle devrait renvoyer la ressource mise à jour.

Les appels à la méthode Delete devraient être idempotents, mais n'ont pas besoin de donner la même réponse. N'importe quel nombre de requêtes Delete devrait aboutir à la suppression (à terme) d'une ressource, mais seule la première requête devrait donner lieu à un code de réussite. Les requêtes suivantes devraient entraîner google.rpc.Code.NOT_FOUND.

Exemple :

// 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;
}