Méthodes standards

Ce chapitre définit le concept des méthodes standards, qui sont 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> Non disponible Liste de ressources*
Get GET <resource URL> Non disponible Ressource*
Create POST <collection URL> Ressource Ressource*
Update PUT or PATCH <resource URL> Ressource Ressource*
Delete DELETE <resource URL> ND google.protobuf.Empty**

*La ressource renvoyée par les méthodes List, Get, Create et Update peut contenir des données partielles si les méthodes acceptent les masques de champ 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 (telles que la mise à jour d'une option ou la création d'une opération de suppression de longue durée, par exemple) doit 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 utilise 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 généralement utilisée pour rechercher des ressources. La méthode List convient aux données d'une seule collection dont la taille est limitée et non mise en cache. Pour des cas plus larges, la méthode personnalisée Search doit ê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) doit être mise en œuvre en tant que méthode BatchGet personnalisée, plutôt qu'en tant que méthode List. Toutefois, si vous disposez déjà d'une méthode List offrant la même fonctionnalité, vous pouvez réutiliser la méthode List à cette fin. Si vous utilisez une méthode BatchGet personnalisée, celle-ci doit être mise en correspondance avec 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;
}

Créer

La méthode Create utilise un nom de ressource parente, 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 doit disposer d'une méthode Create pour chaque type de ressource pouvant être créé.

Mappage HTTP :

  • La méthode Create doit utiliser un verbe HTTP POST.
  • Le message de requête doit contenir un champ parent spécifiant 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 ID 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 doit échouer avec le code d'erreur ALREADY_EXISTS ou utiliser un autre nom de ressource attribué par le serveur. Par ailleurs, la documentation doit clairement stipuler que le nom de la ressource créée peut être différent de celui qui a été transmis.

La méthode Create doit prendre une ressource d'entrée. Ainsi, lorsque le schéma de ressource change, 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 "uniquement en sortie".

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 des ressources modifiables doivent être modifiables par la méthode Update, à l'exception des propriétés qui contiennent le nom ou 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 doit 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 doivent être ignorés.
  • Une méthode Update qui nécessite une sémantique de correctif plus avancée, telle que l'ajout d'un champ répété, doit être disponible via une méthode personnalisée.
  • Si la méthode Update n'accepte que la mise à jour complète des ressources, elle doit utiliser le verbe HTTP PUT. Cependant, une mise à jour complète est fortement déconseillée, car elle présente des problèmes de rétrocompatibilité lors de l'ajout de nouveaux champs de ressource.
  • 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 compatible avec la création de ressources doit également fournir une méthode Create. Cela s'explique par le fait qu'il n'est pas évident de comprendre la création des ressources si la méthode Update est le seul moyen d'y parvenir.

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

Supprimer

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 doit pas s'appuyer sur des informations renvoyées par une méthode Delete, car elle ne peut pas être appelé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 doit renvoyer une réponse vide.
  • Si la méthode Delete lance une opération de longue durée, elle doit renvoyer l'opération de longue durée.
  • Si la méthode Delete marque uniquement la ressource comme étant en cours de suppression, elle doit renvoyer la ressource mise à jour.

Les appels de la méthode Delete doivent être idempotents, mais ne doivent pas nécessairement renvoyer la même réponse. Tout nombre de requêtes Delete doit entraîner la suppression (à terme) d'une ressource, mais seule la première requête doit donner lieu à un code de réussite. Les requêtes ultérieures doivent générer une réponse 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;
}