Questo capitolo definisce il concetto dei metodi standard: List
, Get
,
Create
, Update
e Delete
. I metodi standard riducono la complessità e
aumentano la coerenza. Oltre il 70% dei metodi delle API nel repository delle API di Google sono metodi standard, che ne facilitano l'apprendimento e l'utilizzo.
La tabella seguente descrive come mappare i metodi standard a quelli HTTP:
Metodo standard | Mappatura HTTP | Corpo della richiesta HTTP | Corpo della risposta HTTP |
---|---|---|---|
List |
GET <collection URL> |
N/A | Elenco 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 da metodi List
, Get
, Create
e Update
può contenere dati parziali se i metodi supportano le maschere di 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ò anche restituire un'operazione a lunga esecuzione per le richieste che non vengono completate entro l'intervallo di tempo della singola chiamata API.
Le sezioni seguenti descrivono in dettaglio ciascuno dei metodi standard. Gli esempi mostrano i metodi definiti nei file .proto con annotazioni speciali per le mappature HTTP. Puoi trovare molti esempi che utilizzano metodi standard nel repository delle API di Google.
Listino
Il metodo List
accetta un nome di raccolta e zero o più parametri come input e restituisce un elenco di risorse che corrispondono all'input.
List
è normalmente utilizzato per cercare risorse. List
è adatto ai dati provenienti da un'unica raccolta limitata e non memorizzata nella cache. Per i casi più ampi,
è necessario utilizzare il metodo personalizzato Search
.
Un get batch (come un metodo che prevede più ID risorsa e restituisce un oggetto per ciascuno di questi ID) deve essere implementato come metodo BatchGet
personalizzato, anziché come List
. Tuttavia, se disponi di un metodo List
già esistente che fornisce la stessa funzionalità,
puoi riutilizzare il metodo List
per questo scopo. Se utilizzi un metodo BatchGet
personalizzato, deve essere mappato a HTTP GET
.
Pattern comuni applicabili: impaginazione, ordinamento dei risultati.
Convenzioni di denominazione applicabili: campo filtro, campo risultati
Mappatura HTTP:
- Il metodo
List
deve utilizzare un verboGET
HTTP. - I campi dei messaggi di richiesta che ricevono il nome della raccolta le cui risorse sono elencate devono essere mappate al percorso dell'URL. Se il nome della raccolta corrisponde al percorso dell'URL, l'ultimo segmento del modello di URL (l'ID raccolta) deve essere letterale.
- Tutti i campi del messaggio di richiesta rimanenti verranno mappati ai parametri di ricerca dell'URL.
- Non è presente un corpo della richiesta; la configurazione API non deve dichiarare
una clausola
body
. - Il corpo della risposta deve contenere un elenco di risorse con 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;
}
Recupero
Il metodo Get
accetta un nome risorsa, zero o più parametri, e restituisce la risorsa specificata.
Mappatura HTTP:
- Il metodo
Get
deve utilizzare un verboGET
HTTP. - I campi del messaggio della richiesta che ricevono il nome della risorsa devono essere mappati al percorso dell'URL.
- Tutti i campi del messaggio di richiesta rimanenti verranno mappati ai parametri di ricerca dell'URL.
- Non è presente un corpo della richiesta; la configurazione API non deve dichiarare
una clausola
body
. - La risorsa restituita viene 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
prevede un nome risorsa principale, una risorsa e zero o più parametri. Crea una nuova risorsa sotto quella principale specificata e restituisce la risorsa appena creata.
Se un'API supporta la creazione di risorse, dovrebbe avere un metodo Create
per ogni tipo di risorsa che può essere creata.
Mappatura HTTP:
- Il metodo
Create
deve utilizzare un verboPOST
HTTP. - Il messaggio di richiesta deve avere un campo
parent
che specifichi il nome della risorsa principale in cui creare la risorsa. - Il campo del messaggio di richiesta contenente la risorsa deve mappare il corpo della richiesta HTTP. Se viene utilizzata l'annotazione
google.api.http
per il metodoCreate
, deve utilizzare il modulobody: "<resource_field>"
. - La richiesta potrebbe contenere un campo denominato
<resource>_id
per consentire ai chiamanti di selezionare un ID assegnato al client. Questo campo potrebbe essere all'interno della risorsa. - Tutti i campi del messaggio di richiesta rimanenti verranno mappati ai parametri di ricerca dell'URL.
- La risorsa restituita viene mappata all'intero corpo della risposta HTTP.
Se il metodo Create
supporta un nome risorsa assegnato dal client e
la risorsa esiste già, la richiesta deve non riuscire con il codice di errore
ALREADY_EXISTS
o
utilizzare un nome risorsa assegnato dal server diverso
e la documentazione deve indicare chiaramente che il nome della risorsa creata può essere diverso da quello passato.
Il metodo Create
deve assumere una risorsa input, in modo che quando lo schema di risorse cambia, non è necessario aggiornare sia lo schema di richiesta sia lo schema di risorse. Per i campi delle risorse che non possono essere impostati dai client, i campi devono
essere documentati come "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;
}
Aggiornamento
Il metodo Update
accetta un messaggio di richiesta contenente una risorsa e zero
o più parametri. Aggiorna la risorsa specificata e le relative proprietà e
restituisce la risorsa aggiornata.
Le proprietà delle risorse modificabili devono essere modificabili dal metodo
Update
, ad eccezione delle proprietà che contengono la risorsa's
nome o principale. Le funzionalità per rinominare o spostare una risorsa non devono essere eseguite con il metodo Update
, ma devono invece essere gestite 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 dell'applicazione di patch più avanzata, come l'aggiunta a un campo ripetuto, deve essere reso disponibile da un metodo personalizzato. - Se il metodo
Update
supporta solo l'aggiornamento completo delle risorse, deve utilizzare il verbo HTTPPUT
. Tuttavia, l'aggiornamento completo è sconsigliato, in quanto presenta problemi di compatibilità con le versioni precedenti quando si aggiungono nuovi campi della risorsa. - Il campo del messaggio che riceve il nome della risorsa deve mappare al percorso dell'URL. Il campo potrebbe essere nel messaggio della risorsa stesso.
- Il campo del messaggio di richiesta contenente la risorsa deve mappare il corpo della richiesta.
- Tutti i campi del messaggio di richiesta rimanenti devono essere mappati ai parametri di ricerca dell'URL.
- Il messaggio di risposta deve essere la risorsa aggiornata.
Se l'API accetta nomi di risorse assegnati dal client, il server potrebbe consentire al client di specificare un nome della risorsa inesistente e di crearne una nuova.
In caso contrario, il metodo Update
non deve contenere un nome della risorsa inesistente.
Il codice di errore NOT_FOUND
deve essere utilizzato se è l'unica condizione di errore.
Anche un'API con un metodo Update
che supporta la creazione di risorse deve 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
prevede un nome risorsa e zero o più parametri ed elimina o pianifica l'eliminazione della risorsa specificata.
Il metodo Delete
dovrebbe restituire google.protobuf.Empty
.
Un'API non deve fare affidamento sulle informazioni restituite da un metodo Delete
, in quanto non può essere richiamata ripetutamente.
Mappatura HTTP:
- Il metodo
Delete
deve utilizzare un verboDELETE
HTTP. - I campi del messaggio della richiesta che ricevono il nome della risorsa devono essere mappati al percorso dell'URL.
- Tutti i campi del messaggio di richiesta rimanenti verranno mappati ai parametri di query dell'URL.
- Non è presente un corpo della richiesta; la configurazione API non deve dichiarare
una clausola
body
. - Se il metodo
Delete
rimuove immediatamente la risorsa, deve 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
devono essere
idempotenti, ma non è necessario ottenere la stessa risposta. Qualsiasi numero di
Delete
richieste dovrebbe comportare l'eliminazione di una risorsa (anche se non finale)
ma solo una prima richiesta dovrebbe generare un codice di operazione riuscita. 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;
}