En este capítulo, se analizará cómo usar métodos personalizados para los diseños de API.
Los métodos personalizados son los métodos de API distintos de los 5 métodos estándar. Solo deben usarse para la funcionalidad que no se puede expresar con facilidad a través de los métodos estándar. En general, los diseñadores de API deben elegir los métodos estándar en lugar de métodos personalizados siempre que sea posible. Los métodos estándar tienen una semántica más simple y bien definida con la que la mayoría de los desarrolladores están familiarizados, por lo que son más fáciles de usar y menos propensos a errores. Otra ventaja de los métodos estándar es que la plataforma de API tiene una mejor comprensión y compatibilidad con los métodos estándar, como la facturación, el manejo de errores, el registro y la supervisión.
Un método personalizado se puede asociar con un recurso, una colección o un servicio. Puede tomar una solicitud arbitraria y mostrar una respuesta arbitraria, también admite la solicitud y respuesta de transmisión.
Los nombres de métodos personalizados deben seguir las convenciones de nomenclatura de métodos.
Asignación HTTP
Para los métodos personalizados, se debe usar la siguiente asignación HTTP genérica:
https://service.name/v1/some/resource/name:customVerb
Se usa :
en lugar de /
para separar el verbo personalizado del nombre del recurso a fin de admitir rutas arbitrarias. Por ejemplo, recuperar un archivo se puede asignar a POST /files/a/long/file/name:undelete
.
Las siguientes pautas se aplicarán cuando se elija la asignación HTTP:
- Los métodos personalizados deben usar el verbo HTTP
POST
, ya que tiene la semántica más flexible, excepto los métodos que se entregan como alternativa a get o list, que pueden usarGET
cuando sea posible. Consulta la tercera viñeta para obtener información específica. - Los métodos personalizados no deben usar
PATCH
HTTP, pero pueden usar otros verbos HTTP. En estos casos, los métodos deben seguir la semántica HTTP estándar para ese verbo. - En particular, los métodos personalizados que usan
GET
HTTP deben ser idempotentes y no tener efectos secundarios. Por ejemplo, los métodos personalizados que implementan vistas especiales en el recurso deben usarGET
HTTP. - Los campos de mensaje de solicitud que reciben el nombre del recurso o colección que se asocia al método personalizado deben asignarse a la ruta de URL.
- La ruta de URL debe terminar con un sufijo que consiste en dos puntos seguidos por el verbo personalizado.
- Si el verbo HTTP que se usa para el método personalizado permite un cuerpo de solicitud HTTP (se aplica a
POST
,PUT
,PATCH
o un verbo HTTP personalizado), la configuración de HTTP de ese método personalizado debe usar la cláusulabody: "*"
y todos los campos de mensaje de solicitud restantes deben asignarse al cuerpo de la solicitud HTTP. - Si el verbo HTTP que se usa para el método personalizado no admite un cuerpo de solicitud HTTP (
GET
,DELETE
), la configuración HTTP de ese método no debe usar la cláusulabody
en absoluto y todos los campos del mensaje de solicitud restantes deben asignarse a los parámetros de consulta URL.
ADVERTENCIA: Si un servicio implementa varias API, el productor de la API debe crear con cuidado la configuración del servicio para evitar conflictos de verbos personalizados entre las API.
// This is a service level custom method.
rpc Watch(WatchRequest) returns (WatchResponse) {
// Custom method maps to HTTP POST. All request parameters go into body.
option (google.api.http) = {
post: "/v1:watch"
body: "*"
};
}
// This is a collection level custom method.
rpc ClearEvents(ClearEventsRequest) returns (ClearEventsResponse) {
option (google.api.http) = {
post: "/v3/events:clear"
body: "*"
};
}
// This is a resource level custom method.
rpc CancelEvent(CancelEventRequest) returns (CancelEventResponse) {
option (google.api.http) = {
post: "/v3/{name=events/*}:cancel"
body: "*"
};
}
// This is a batch get custom method.
rpc BatchGetEvents(BatchGetEventsRequest) returns (BatchGetEventsResponse) {
// The batch get method maps to HTTP GET verb.
option (google.api.http) = {
get: "/v3/events:batchGet"
};
}
Casos prácticos
Las siguientes son algunas situaciones adicionales en las que los métodos personalizados pueden ser la elección correcta:
- Reiniciar una máquina virtual. Las alternativas de diseño podrían ser “crear un recurso de reinicio en una colección de reinicios”, que parece demasiado compleja, o “la máquina virtual tiene un estado mutable que el cliente puede actualizar de EN EJECUCIÓN a REINICIANDO”, lo que crearía interrogantes sobre qué otras transiciones de estado son posibles. Además, el reinicio es un concepto bien conocido que se puede traducir bien a un método personalizado que satisface de forma intuitiva las expectativas del desarrollador.
- Enviar correo electrónico. Crear un mensaje de correo electrónico no siempre implica enviarlo (borrador). En comparación con la alternativa de diseño (mover un mensaje a una colección de “Bandeja de salida”), el método personalizado tiene la ventaja de que el usuario de la API puede descubrirlo con mayor facilidad y modelar el concepto de forma más directa.
- Ascender a un empleado. Si se implementa como una
update
estándar, el cliente tendría que replicar las políticas corporativas que rigen el proceso de ascenso para garantizar que el ascenso pase al nivel correcto, dentro de la misma escala de la carrera, etcétera. - Métodos por lotes. Para los métodos vitales de rendimiento, puede ser útil proporcionar métodos por lotes personalizados a fin de reducir la sobrecarga por solicitud. Por ejemplo, accounts.locations.batchGet.
Los siguientes son algunos ejemplos en los que un método estándar se ajusta mejor que un método personalizado:
- Consultar recursos con diferentes parámetros de consulta (usar el método
list
estándar con el filtrado de lista estándar) - Cambio de propiedad de recurso simple (usar el método
update
estándar con máscara de campo) - Descartar una notificación (usar el método
delete
estándar)
Métodos personalizados comunes
La lista seleccionada de nombres de métodos personalizados de uso común o útiles se encuentra a continuación. Los diseñadores de API deben considerar estos nombres antes de ingresar sus propios nombres para facilitar la coherencia entre las API.
Nombre del método | Verbo personalizado | Verbo HTTP | Nota |
---|---|---|---|
Cancel |
:cancel |
POST |
Cancela una operación pendiente, como operations.cancel . |
BatchGet |
:batchGet |
GET |
get por lotes de varios recursos. Consulta los detalles en la descripción de List. |
Move |
:move |
POST |
Mueve un recurso de un superior a otro, como folders.move . |
Search |
:search |
GET |
Alternativa a List para recuperar datos que no cumplan con la semántica de List, como services.search . |
Undelete |
:undelete |
POST |
Restablece un recurso que se borró anteriormente, como services.undelete . El período de retención recomendado es de 30 días. |