En este documento, se presentan técnicas que puedes usar para mejorar el rendimiento de tu aplicación. En algunos casos, se usan ejemplos de otras API o de API genéricas para ilustrar las ideas presentadas. Sin embargo, los mismos conceptos se aplican a la API de Google Drive.
Compresión con gzip
Una forma fácil y conveniente de reducir el ancho de banda necesario para cada solicitud es habilitar la compresión gzip. Aunque esto requiere un tiempo de CPU adicional para descomprimir los resultados, la compensación con los costos de la red suele hacer que valga la pena.
Si quieres recibir una respuesta codificada en gzip, debes establecer un encabezado de Accept-Encoding
y modificar tu usuario-agente para que contenga la string gzip
. A continuación, se presenta un ejemplo de encabezados HTTP formados de manera correcta para habilitar la compresión gzip:
Accept-Encoding: gzip User-Agent: my program (gzip)
Trabaja con recursos parciales
Otra forma de mejorar el rendimiento de tus llamadas a la API es enviar y recibir solo la parte de los datos que te interesa. Esto permite que tu aplicación evite la transferencia, el análisis y el almacenamiento de campos innecesarios, por lo que pueda usar recursos como la red, la CPU y la memoria con más eficiencia.
Existen los siguientes dos tipos de solicitudes parciales:
- Respuesta parcial: una solicitud en la que especificas qué campos incluir en la respuesta (usa el parámetro de la solicitud de
fields
). - Parche: una solicitud de actualización en la que envías solo los campos que deseas cambiar (usa el verbo HTTP
PATCH
).
En las siguientes secciones, se proporcionan más detalles sobre cómo realizar solicitudes parciales.
Respuesta parcial
De forma predeterminada, el servidor muestra la representación completa de un recurso después de procesar las solicitudes. Para lograr un mejor rendimiento, puedes pedirle al servidor que envíe solo los campos que realmente necesitas y obtener una respuesta parcial en su lugar.
Si quieres solicitar una respuesta parcial, usa el parámetro de solicitud de fields
para especificar los campos que deseas que se muestren. Puedes usar este parámetro con cualquier solicitud que muestre datos de respuesta.
Ten en cuenta que el parámetro de fields
solo afecta a los datos de respuesta; no afecta a los datos que necesitas enviar, si los hay. Para reducir la cantidad de datos que envías cuando modificas recursos, usa una solicitud de parche.
Ejemplo
Parche (actualización parcial)
También puedes evitar el envío de datos innecesarios cuando modificas recursos. Si quieres enviar datos actualizados solo para los campos específicos que modificas, usa el verbo HTTP PATCH
. La semántica de parches descrita en este documento es diferente (y más simple) de lo que era para la implementación anterior de GData de actualización parcial.
En el siguiente ejemplo, se muestra cómo el uso de un parche minimiza los datos que necesitas enviar para realizar una actualización pequeña.
Ejemplo
Controla la respuesta a un parche
Después de procesar una solicitud de parche válida, la API muestra un código de respuesta HTTP 200 OK
junto con la representación completa del recurso modificado. Si la API usa ETags, el servidor actualiza los valores de ETag cuando procesa con éxito una solicitud de parche, al igual que lo hace con PUT
.
La solicitud de parche muestra la representación de recursos completa, a menos que uses el parámetro de fields
para reducir la cantidad de datos que se muestran.
Si una solicitud de parche genera un estado de recursos nuevo que no es válido de manera sintáctica o semántica, el servidor muestra un código de estado HTTP 400 Bad Request
o 422 Unprocessable Entity
y el estado de recursos permanece igual. Por ejemplo, si intentas borrar el valor de un campo obligatorio, el servidor muestra un error.
Notación alternativa cuando no se admite el verbo HTTP PATCH
Si tu firewall no permite solicitudes HTTP PATCH
, entonces haz una solicitud HTTP POST
y configura el encabezado de anulación como PATCH
, como se muestra a continuación:
POST https://www.googleapis.com/... X-HTTP-Method-Override: PATCH ...
Diferencia entre parche y actualización
En la práctica, cuando envías datos para una solicitud de actualización que usa el verbo HTTP PUT
, solo necesitas enviar los campos obligatorios o los opcionales; si envías valores para los campos que establece el servidor, se ignoran. Aunque esto puede parecer otra forma de hacer una actualización parcial, este enfoque tiene algunas limitaciones. Con las actualizaciones que usan el verbo HTTP PUT
, la solicitud falla si no proporcionas los parámetros obligatorios y borra los datos establecidos antes si no proporcionas los parámetros opcionales.
Por esta razón, es mucho más seguro usar un parche. Solo debes proporcionar datos para los campos que deseas cambiar; los campos que omites no se borran. La única excepción a esta regla se produce con la repetición de elementos o arreglos: si omites todos, se mantienen tal como están; si proporcionas alguno de ellos, todo el conjunto se reemplaza por el conjunto que proporciones.
Utiliza solicitudes por lotes
En este documento, se muestra cómo agrupar llamadas a la API a fin de reducir la cantidad de conexiones HTTP que debe hacer el cliente.
Este documento trata, en particular, sobre cómo hacer una solicitud por lotes mediante el envío de una solicitud HTTP. Sin embargo, si usas una biblioteca cliente de Google para realizar una solicitud por lotes, debes consultar la documentación sobre bibliotecas cliente.
Descripción general
Cada conexión HTTP que tu cliente realiza da como resultado una cierta cantidad de sobrecarga. La API de Google Drive admite el procesamiento por lotes, a fin de permitir que tu cliente coloque varias llamadas a la API en una sola solicitud HTTP.
A continuación, se detallan algunos ejemplos de situaciones en las que te sería útil usar el procesamiento por lotes:
- Recuperar metadatos de una gran cantidad de archivos
- Actualizar metadatos o propiedades de forma masiva
- Cambiar los permisos de una gran cantidad de archivos, como agregar un usuario o grupo nuevo
- Sincroniza los datos del cliente local por primera vez o después de estar sin conexión durante un período prolongado.
En cada caso, en lugar de enviar cada llamada por separado, puedes agruparlas en una única solicitud HTTP. Todas las solicitudes internas deben ir en la misma API de Google.
Tienes un límite de 100 llamadas por cada solicitud por lotes. Si necesitas hacer más llamadas, usa varias solicitudes por lotes.
Nota: El sistema por lotes para la API de Google Drive emplea la misma sintaxis que el sistema de procesamiento por lotes OData, pero difiere en la semántica.
Entre las restricciones adicionales, se incluyen las siguientes:
- Es posible que las solicitudes por lotes con más de 100 llamadas generen un error.
- Hay un límite de 8,000 caracteres para la longitud de la URL de cada solicitud interna.
- Google Drive no admite operaciones por lotes para contenido multimedia, ya sea para subir o descargar archivos, o para exportarlos.
Detalles del lote
Una solicitud por lotes consta de varias llamadas a la API combinadas en una solicitud HTTP, que pueden enviarse al batchPath
especificado en el documento de descubrimiento de la API. La ruta de acceso predeterminada es /batch/api_name/api_version
. En esta sección, se describe la sintaxis del lote en detalle; más adelante, se muestra un ejemplo.
Nota: Un conjunto de solicitudes n agrupadas se considera en tu límite de uso como solicitudes n, no como una sola. La solicitud por lotes se divide en un conjunto de solicitudes antes de procesarse.
Formato de una solicitud por lotes
Una solicitud por lotes es una solicitud HTTP estándar que contiene múltiples llamadas a la API de Google Drive, con el tipo de contenido multipart/mixed
. Dentro de esa solicitud HTTP principal, cada una de las partes contiene una solicitud HTTP anidada.
Cada parte comienza con su propio encabezado HTTP Content-Type: application/http
. También puede tener un encabezado opcional Content-ID
. Sin embargo, los encabezados de partes solo están allí para marcar el comienzo de la parte; están separados de la solicitud anidada. Una vez que el servicio desenvuelve la solicitud por lotes en diferentes solicitudes, los encabezados de las partes se ignoran.
El cuerpo de cada parte es en sí mismo una solicitud HTTP completa, con su propio verbo, URL, encabezados y cuerpo. La solicitud HTTP debe contener solamente la parte de la ruta de la URL; no se admiten URL enteras en las solicitudes por lotes.
Los encabezados HTTP para la solicitud por lotes externa, excepto por los encabezados Content-
, como Content-Type
, se aplican a cada solicitud en el lote. Si especificas cierto encabezado HTTP tanto en la solicitud externa como en una llamada individual, el valor del encabezado de la llamada individual reemplaza el valor del encabezado de la solicitud por lotes externa. Los encabezados de una llamada individual solo se aplican a esa llamada.
Por ejemplo, si proporcionas un encabezado de autorización para una llamada específica, ese encabezado se aplica solamente a esa llamada. Si proporcionas un encabezado de autorización para la solicitud externa, se aplica a todas las llamadas individuales, a menos que la reemplacen con encabezados de autorización propios.
Cuando el servidor recibe la solicitud por lotes, aplica los encabezados y parámetros de consulta de la solicitud externa (según corresponda) a cada parte y, a continuación, trata cada parte como una solicitud HTTP separada.
Respuesta a una solicitud por lotes
La respuesta del servidor es una sola respuesta HTTP estándar con un tipo de contenido multipart/mixed
; cada parte es la respuesta a una de las solicitudes de la solicitud por lotes, en el mismo orden que las solicitudes.
Como las partes de la solicitud, cada parte de respuesta contiene una respuesta HTTP completa, que incluye un código de estado, encabezados y un cuerpo. Además, cada una está precedida por un encabezado Content-Type
que marca el comienzo de la parte.
Si cierta parte de la solicitud tenía un encabezado Content-ID
, la parte correspondiente de la respuesta tendrá un encabezado Content-ID
que coincida y un valor original precedido por la string response-
, como se muestra en el siguiente ejemplo.
Nota: Es posible que el servidor realice llamadas en cualquier orden. No cuentes con que se ejecutarán en el orden en que las especificaste. Si quieres garantizar que dos llamadas sucedan en un orden determinado, no puedes enviarlas en una misma solicitud; en cambio, envía la primera sola, espera una respuesta y, luego, envía la segunda.
Ejemplo
En el siguiente ejemplo, se muestra el uso del procesamiento por lotes con la API de Google Drive.
Ejemplo de solicitud por lotes
POST https://www.googleapis.com/batch/drive/v3 Accept-Encoding: gzip User-Agent: Google-HTTP-Java-Client/1.20.0 (gzip) Content-Type: multipart/mixed; boundary=END_OF_PART Content-Length: 963--END_OF_PART Content-Length: 337 Content-Type: application/http content-id: 1 content-transfer-encoding: binary
POST https://www.googleapis.com/drive/v3/files/fileId/permissions?fields=id Authorization: Bearer authorization_token Content-Length: 70 Content-Type: application/json; charset=UTF-8
{ "emailAddress":"example@appsrocks.com", "role":"writer", "type":"user" } --END_OF_PART Content-Length: 353 Content-Type: application/http content-id: 2 content-transfer-encoding: binary
POST https://www.googleapis.com/drive/v3/files/fileId/permissions?fields=id&sendNotificationEmail=false Authorization: Bearer authorization_token Content-Length: 58 Content-Type: application/json; charset=UTF-8
{ "domain":"appsrocks.com", "role":"reader", "type":"domain" } --END_OF_PART--
Ejemplo de respuesta por lotes
Esta es la respuesta a la solicitud de ejemplo de la sección anterior.
HTTP/1.1 200 OK Alt-Svc: quic=":443"; p="1"; ma=604800 Server: GSE Alternate-Protocol: 443:quic,p=1 X-Frame-Options: SAMEORIGIN Content-Encoding: gzip X-XSS-Protection: 1; mode=block Content-Type: multipart/mixed; boundary=batch_6VIxXCQbJoQ_AATxy_GgFUk Transfer-Encoding: chunked X-Content-Type-Options: nosniff Date: Fri, 13 Nov 2015 19:28:59 GMT Cache-Control: private, max-age=0 Vary: X-Origin Vary: Origin Expires: Fri, 13 Nov 2015 19:28:59 GMT--batch_6VIxXCQbJoQ_AATxy_GgFUk Content-Type: application/http Content-ID: response-1
HTTP/1.1 200 OK Content-Type: application/json; charset=UTF-8 Date: Fri, 13 Nov 2015 19:28:59 GMT Expires: Fri, 13 Nov 2015 19:28:59 GMT Cache-Control: private, max-age=0 Content-Length: 35
{ "id": "12218244892818058021i" }
--batch_6VIxXCQbJoQ_AATxy_GgFUk Content-Type: application/http Content-ID: response-2
HTTP/1.1 200 OK Content-Type: application/json; charset=UTF-8 Date: Fri, 13 Nov 2015 19:28:59 GMT Expires: Fri, 13 Nov 2015 19:28:59 GMT Cache-Control: private, max-age=0 Content-Length: 35
{ "id": "04109509152946699072k" }
--batch_6VIxXCQbJoQ_AATxy_GgFUk--
Muestra campos específicos de la solicitud
Si no especificas el parámetro fields
, el servidor muestra un conjunto predeterminado de
campos específicos del método. Por ejemplo, el método files.list
solo muestra los campos kind
, id
, name
y mimeType
.
Es posible que los campos predeterminados que se muestran no sean los que necesitas. Si deseas especificar qué campos mostrar en la respuesta, usa el parámetro del sistema fields
.
Para obtener más información, consulta Cómo mostrar campos específicos.
Para todos los métodos de los recursos about
, comments
(sin incluir delete
) y replies
(sin incluir delete
), debes configurar el parámetro fields
. Estos métodos no muestran un conjunto predeterminado de campos.