Questo capitolo definisce il concetto di metodi standard, ovvero List
, Get
, Create
, Update
e Delete
. I metodi standard riducono la complessità e
aumentano la coerenza. Oltre il 70% dei metodi API nel repository delle API di Google sono standard, il che li rende molto più facili da imparare e utilizzare.
La tabella seguente descrive come mappare i metodi standard ai metodi HTTP:
Metodo standard | Mappatura HTTP | Corpo della richiesta HTTP | Corpo risposta HTTP |
---|---|---|---|
List |
GET <collection URL> |
N/A | Elenco delle risorse* |
Get |
GET <resource URL> |
N/A | Risorsa* |
Create |
POST <collection URL> |
Risorsa | Risorsa* |
Update |
PUT or PATCH <resource URL> |
Risorsa | Risorsa* |
Delete |
DELETE <resource URL> |
N/A | google.protobuf.Empty ** |
*La risorsa restituita dai metodi List
, Get
, Create
e Update
potrebbe contenere dati parziali se i metodi supportano le maschere dei campi di risposta, che specificano un sottoinsieme di campi da restituire.
In alcuni casi, la piattaforma API supporta in modo nativo le maschere di campo per tutti i metodi.
**La risposta restituita da un metodo Delete
che non rimuove immediatamente la risorsa (ad esempio l'aggiornamento di un flag o la creazione di un'operazione di eliminazione a lunga esecuzione) deve contenere l'operazione a lunga esecuzione o la risorsa modificata.
Un metodo standard può restituire anche un'operazione a lunga esecuzione per le richieste che non vengono completate nell'intervallo di tempo della singola chiamata API.
Le seguenti sezioni descrivono in dettaglio ogni metodo standard. Gli esempi mostrano i metodi definiti nei file .proto con annotazioni speciali per le mappature HTTP. Puoi trovare molti esempi che utilizzano i metodi standard nel repository delle API di Google.
Elenco
Il metodo List
prende il nome della raccolta e zero o più parametri come input e restituisce un elenco di risorse che corrispondono all'input.
List
è comunemente utilizzato per cercare risorse. List
è adatto ai dati di una singola raccolta con dimensioni limitate e non memorizzata nella cache. Per casi più generici, dovrebbe utilizzare il metodo personalizzato Search
.
Un recupero batch (ad esempio un metodo che accetta più ID risorsa
e restituisce un oggetto per ciascuno di questi ID) deve essere implementato come metodo BatchGet
personalizzato anziché come List
. Tuttavia, se hai già un metodo List
che offre la stessa funzionalità, puoi riutilizzare il metodo List
per questo scopo. Se utilizzi un metodo BatchGet
personalizzato, questo dovrebbe essere mappato a HTTP GET
.
Pattern comuni applicabili: paginazione, ordinamento dei risultati.
Convenzioni di denominazione applicabili: campo filtro, campo risultati
Mappatura HTTP:
- Il metodo
List
deve utilizzare un verbo HTTPGET
. - I campi del messaggio di richiesta che ricevono il nome della raccolta le cui risorse sono elencate devono essere mappati al percorso dell'URL. Se il nome della raccolta viene mappato al percorso dell'URL, l'ultimo segmento del modello di URL (l'ID raccolta) deve essere letterale.
- Tutti i restanti campi del messaggio di richiesta saranno mappati ai parametri di ricerca dell'URL.
- Non esiste un corpo della richiesta; la configurazione API non deve dichiarare una clausola
body
. - Il corpo della risposta deve contenere un elenco di risorse insieme a metadati facoltativi.
Esempio:
// 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
Il metodo Get
prende un nome di risorsa, zero o più parametri e restituisce la risorsa specificata.
Mappatura HTTP:
- Il metodo
Get
deve utilizzare un verbo HTTPGET
. - I campi del messaggio di richiesta che ricevono il nome della risorsa devono essere mappati al percorso dell'URL.
- Tutti i restanti campi del messaggio di richiesta saranno mappati ai parametri di ricerca dell'URL.
- Non esiste un corpo della richiesta; la configurazione API non deve dichiarare una clausola
body
. - La risorsa restituita deve essere mappata all'intero corpo della risposta.
Esempio:
// 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;
}
Crea
Il metodo Create
utilizza un nome risorsa padre, una risorsa e zero o più parametri. Crea una nuova risorsa sotto l'elemento padre specificato e restituisce la risorsa appena creata.
Se un'API supporta la creazione di risorse, deve avere un metodo Create
per ogni tipo di risorsa creabile.
Mappatura HTTP:
- Il metodo
Create
deve utilizzare un verbo HTTPPOST
. - Il messaggio di richiesta deve contenere un campo
parent
che specifica il nome della risorsa padre in cui deve essere creata la risorsa. - Il campo del messaggio della richiesta contenente la risorsa deve essere mappato al corpo della richiesta HTTP. Se per il metodo
Create
viene utilizzata l'annotazionegoogle.api.http
, deve essere usato il modulobody: "<resource_field>"
. - La richiesta può contenere un campo denominato
<resource>_id
per consentire ai chiamanti di selezionare un ID assegnato dal client. Questo campo potrebbe trovarsi all'interno della risorsa. - Tutti i restanti campi del messaggio di richiesta saranno mappati ai parametri di query dell'URL.
- La risorsa restituita deve essere mappata all'intero corpo della risposta HTTP.
Se il metodo Create
supporta il nome della risorsa assegnato dal client e la risorsa esiste già, la richiesta dovrebbe avere esito negativo con codice di errore ALREADY_EXISTS
o utilizzare un nome di risorsa assegnato dal server diverso e la documentazione deve indicare chiaramente che il nome della risorsa creata potrebbe essere diverso da quello trasmesso.
Il metodo Create
deve prendere una risorsa di input in modo che, quando lo schema della risorsa cambia, non sia necessario aggiornare sia lo schema delle richieste sia lo schema delle risorse. Per i campi delle risorse che non possono essere impostati dai client, devono essere documentati come campi "Solo output".
Esempio:
// 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;
}
Aggiorna
Il metodo Update
accetta un messaggio di richiesta contenente una risorsa e zero
o più parametri. Aggiorna la risorsa specificata e le sue proprietà
e restituisce la risorsa aggiornata.
Le proprietà delle risorse modificabili devono essere modificabili dal metodo Update
, ad eccezione delle proprietà che contengono il nome o l'elemento padre della risorsa. Qualsiasi funzionalità
per rinominare o spostare una risorsa non deve avvenire nel metodo Update
e dovrà essere gestita da un metodo personalizzato.
Mappatura HTTP:
- Il metodo
Update
standard deve supportare l'aggiornamento parziale delle risorse e utilizzare il verbo HTTPPATCH
con un campoFieldMask
denominatoupdate_mask
. I campi di output forniti dal client come input devono essere ignorati. - Un metodo
Update
che richiede una semantica di applicazione patch più avanzata, ad esempio l'aggiunta a un campo ripetuto, deve essere reso disponibile con un metodo personalizzato. - Se il metodo
Update
supporta solo l'aggiornamento completo delle risorse, deve utilizzare il verbo HTTPPUT
. Tuttavia, l'aggiornamento completo è sconsigliato perché presenta problemi di compatibilità con le versioni precedenti durante l'aggiunta di nuovi campi delle risorse. - Il campo del messaggio che riceve il nome della risorsa deve essere mappato al percorso dell'URL. Il campo potrebbe essere presente nel messaggio della risorsa stesso.
- Il campo del messaggio della richiesta contenente la risorsa deve essere mappato al corpo della richiesta.
- Tutti i restanti campi del messaggio di richiesta devono essere mappati ai parametri di query dell'URL.
- Il messaggio di risposta deve corrispondere alla risorsa aggiornata.
Se l'API accetta nomi di risorse assegnati dal client, il server potrebbe consentire al client di specificare un nome di risorsa inesistente e di crearne una nuova.
In caso contrario, il metodo Update
dovrebbe avere esito negativo con un nome risorsa inesistente.
Il codice di errore NOT_FOUND
deve essere utilizzato se è l'unica condizione di errore.
Un'API con un metodo Update
che supporta la creazione di risorse dovrebbe fornire anche un metodo Create
. La motivazione è che non è chiaro come creare risorse se il metodo Update
è l'unico modo per farlo.
Esempio:
// 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;
}
Elimina
Il metodo Delete
prende un nome di risorsa e zero o più parametri ed elimina o pianifica l'eliminazione della risorsa specificata.
Il metodo Delete
deve restituire google.protobuf.Empty
.
Un'API non deve basarsi su informazioni restituite da un metodo Delete
, poiché non può essere richiamata ripetutamente.
Mappatura HTTP:
- Il metodo
Delete
deve utilizzare un verbo HTTPDELETE
. - I campi del messaggio di richiesta che ricevono il nome della risorsa devono essere mappati al percorso dell'URL.
- Tutti i restanti campi del messaggio di richiesta saranno mappati ai parametri query dell'URL.
- Non esiste un corpo della richiesta; la configurazione API non deve dichiarare una clausola
body
. - Se il metodo
Delete
rimuove immediatamente la risorsa, dovrebbe restituire una risposta vuota. - Se il metodo
Delete
avvia un'operazione a lunga esecuzione, dovrebbe restituire l'operazione a lunga esecuzione. - Se il metodo
Delete
contrassegna solo la risorsa come eliminata, dovrebbe restituire la risorsa aggiornata.
Le chiamate al metodo Delete
dovrebbero essere idempotenti in effetto, ma non devono generare la stessa risposta. Un numero qualsiasi di richieste Delete
dovrebbe comportare l'eliminazione di una risorsa, ma solo la prima richiesta dovrebbe comportare un codice di esito positivo. Le richieste successive dovrebbero generare un google.rpc.Code.NOT_FOUND
.
Esempio:
// 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;
}