Nelle API orientate alle risorse, le risorse sono entità denominate, mentre i nomi delle risorse sono i relativi identificatori. Ogni risorsa deve avere un proprio nome univoco. Il nome della risorsa è composto dall'ID della risorsa stessa, dagli ID di eventuali risorse padre e dal nome del relativo servizio API. Di seguito analizzeremo gli ID risorsa e come viene strutturato il nome della risorsa.
Le API gRPC devono utilizzare URI senza schema per i nomi delle risorse. In genere seguono le convenzioni degli URL REST e si comportano in modo molto simile ai percorsi dei file di rete. Possono essere facilmente mappati a URL REST: per maggiori dettagli, consulta la sezione Metodi standard.
Una raccolta è un tipo speciale di risorsa che contiene un elenco di risorse secondarie di tipo identico. Ad esempio, una directory è una raccolta di risorse di file. L'ID risorsa di una raccolta è chiamato ID raccolta.
Il nome della risorsa è organizzato in modo gerarchico utilizzando ID raccolta e ID risorsa, separati da barre. Se una risorsa contiene una risorsa secondaria, il nome di quest'ultima viene formato specificando il nome della risorsa padre seguito dall'ID della risorsa secondaria, sempre separato da barre.
Esempio 1: un servizio di archiviazione ha una raccolta buckets
, in cui ogni bucket ha una raccolta di objects
:
Nome servizio API | ID raccolta | ID risorsa | ID raccolta | ID risorsa |
---|---|---|---|---|
//storage.googleapis.com | /buckets | /bucket-id | /objects | /object-id |
Esempio 2: un servizio email ha una raccolta di users
. Ogni utente ha una
risorsa secondaria settings
e la sottorisorsa settings
ha una serie di
altre risorse secondarie, tra cui customFrom
:
Nome servizio API | ID raccolta | ID risorsa | ID risorsa | ID risorsa |
---|---|---|---|---|
//mail.googleapis.com | /users | /name@example.com | /settings | /customFrom |
Un producer di API può scegliere qualsiasi valore accettabile per gli ID risorsa e raccolta, purché siano univoci all'interno della gerarchia delle risorse. Di seguito puoi trovare ulteriori linee guida per la scelta degli ID risorsa e raccolta appropriati.
Suddividendo il nome della risorsa, ad esempio name.split("/")[n]
, è possibile ottenere i singoli ID raccolta e ID risorsa, supponendo che nessuno dei segmenti contenga una barra.
Nome completo risorsa
Un URI senza schema costituito da un nome di servizio API compatibile con DNS e un percorso delle risorse. Il percorso della risorsa è anche noto come nome risorsa relativa. Ad esempio:
"//library.googleapis.com/shelves/shelf1/books/book2"
Il nome del servizio API consente ai client di individuare l'endpoint del servizio API; potrebbe essere un nome DNS falso per i servizi solo per uso interno. Se il nome del servizio API è evidente dal contesto, spesso vengono utilizzati i nomi delle risorse relativi.
Nome risorsa relativa
Un percorso URI (path-noscheme) senza il carattere "/" iniziale. Identifica una risorsa all'interno del servizio API. Ad esempio:
"shelves/shelf1/books/book2"
ID risorsa
Un ID risorsa è solitamente costituito da uno o più segmenti URI non vuoti (segment-nz-nc) che identificano la risorsa all'interno della risorsa padre. Vedi gli esempi precedenti. L'ID risorsa non finale in un nome risorsa deve avere esattamente un segmento URL, mentre l'ID risorsa finale in un nome risorsa può avere più di un segmento URI. Ad esempio:
ID raccolta | ID risorsa |
---|---|
file in conflitto | source/py/parser.py |
Se possibile, i servizi API devono utilizzare ID risorsa idonei per gli URL. Gli ID risorsa devono essere chiaramente documentati se vengono assegnati dal client, dal server o da entrambi. Ad esempio, i nomi dei file vengono generalmente assegnati dai client, mentre gli ID messaggio email vengono in genere assegnati dai server.
ID raccolta
Un segmento URI non vuoto (segment-nz-nc) che identifica la risorsa di raccolta all'interno della risorsa padre, vedi gli esempi precedenti.
Poiché gli ID raccolta spesso appaiono nelle librerie client generate, devono essere conformi ai seguenti requisiti:
- Deve essere identificatori C/C++ validi.
- Deve essere in forma plurale con maiuscole e minuscole. Se il termine non ha adatto forma plurale, ad esempio "prove" e "meteo", è necessario utilizzare la forma al singolare dov.
- Devi utilizzare termini inglesi chiari e concisi.
- I termini eccessivamente generici devono essere evitati o qualificati. Ad esempio,
rowValues
è preferito rispetto avalues
. I seguenti termini dovrebbero essere eviti senza alcuna qualifica:- elementi
- entries
- istanze
- elementi
- oggetti
- le risorse selezionate
- types
- valori
Confronto tra nome risorsa e URL
Anche se i nomi completi delle risorse assomigliano a URL normali, non sono la stessa cosa. Una singola risorsa può essere esposta da versioni API, protocolli API o endpoint di rete diversi. Il nome completo della risorsa non specifica queste informazioni, perciò deve essere mappata a una versione e a un protocollo API specifici per l'uso effettivo.
Per utilizzare un nome completo della risorsa tramite le API REST, deve essere convertito in un URL REST aggiungendo lo schema HTTPS prima del nome del servizio, aggiungendo la versione principale dell'API prima del percorso della risorsa ed effettuando l'escape dell'URL del percorso della risorsa. Ad esempio:
// This is a calendar event resource name.
"//calendar.googleapis.com/users/john smith/events/123"
// This is the corresponding HTTP URL.
"https://calendar.googleapis.com/v3/users/john%20smith/events/123"
Nome risorsa come stringa
Le API di Google devono rappresentare i nomi delle risorse utilizzando stringhe semplici, a meno che non sia un problema di compatibilità con le versioni precedenti. I nomi delle risorse devono essere gestiti come normali percorsi di file. Quando il nome di una risorsa viene passato tra componenti diversi, deve essere considerato un valore atomico e non deve subire alcuna perdita di dati.
Per le definizioni delle risorse, il primo campo deve essere un campo stringa per il nome della risorsa e deve essere denominato name
.
Ad esempio:
service LibraryService {
rpc GetBook(GetBookRequest) returns (Book) {
option (google.api.http) = {
get: "/v1/{name=shelves/*/books/*}"
};
};
rpc CreateBook(CreateBookRequest) returns (Book) {
option (google.api.http) = {
post: "/v1/{parent=shelves/*}/books"
body: "book"
};
};
}
message Book {
// Resource name of the book. It must have the format of "shelves/*/books/*".
// For example: "shelves/shelf1/books/book2".
string name = 1;
// ... other properties
}
message GetBookRequest {
// Resource name of a book. For example: "shelves/shelf1/books/book2".
string name = 1;
}
message CreateBookRequest {
// Resource name of the parent resource where to create the book.
// For example: "shelves/shelf1".
string parent = 1;
// The Book resource to be created. Client must not set the `Book.name` field.
Book book = 2;
}
Nota: per garantire la coerenza dei nomi delle risorse, la barra iniziale non deve essere acquisita da nessuna variabile del modello di URL. Ad esempio, deve utilizzare il modello di URL "/v1/{name=shelves/*/books/*}"
anziché
"/v1{name=/shelves/*/books/*}"
.
Domande
D: Perché non utilizzare gli ID risorsa per identificare una risorsa?
Per ogni sistema di grandi dimensioni, esistono molti tipi di risorse. Per utilizzare gli ID risorsa per identificare una risorsa, in realtà utilizziamo una tupla specifica della risorsa per identificare una risorsa, ad esempio (bucket, object)
o (user, album, photo)
. Crea diversi problemi principali:
- Gli sviluppatori devono comprendere e ricordare queste tuple anonime.
- Il passaggio delle tuple è generalmente più difficile del passaggio delle stringhe.
- Le infrastrutture centralizzate, come i sistemi di logging e controllo dell'accesso dell'accesso, non comprendono le tuple specializzate.
- Le tuple specializzate limitano la flessibilità di progettazione delle API, ad esempio forniscono interfacce API riutilizzabili. Ad esempio, le operazioni a lunga esecuzione possono funzionare con molte altre interfacce API perché utilizzano nomi di risorse flessibili.
D: Perché il campo del nome della risorsa si chiama name
anziché id
?
Il campo del nome della risorsa è denominato in base al concetto di "nome" della risorsa. In
generale, riteniamo che il concetto di name
confonda gli sviluppatori. Ad esempio, il nome file è davvero solo il nome o il percorso completo? Riservando il campo
standard name
, gli sviluppatori sono costretti a scegliere un termine più appropriato,
come display_name
, title
o full_name
.
D: Come devo generare e analizzare i nomi delle risorse?
I nomi delle risorse si comportano come i percorsi dei file. Puoi utilizzare printf()
per generare i nomi delle risorse a partire dagli ID delle risorse. Puoi usare split()
per analizzare i nomi
delle risorse in ID delle risorse. Tieni presente che alcuni ID risorsa finali possono avere più segmenti URI separati da /
, ad esempio il percorso del file.