Buscar..


Observaciones

Las API HTTP utilizan un amplio espectro de verbos HTTP y, por lo general, devuelven respuestas JSON o XML.

Crear un recurso

No todos están de acuerdo en cuál es el método más semánticamente correcto para la creación de recursos. Por lo tanto, su API podría aceptar POST o PUT , o cualquiera.

El servidor debe responder con 201 Created si el recurso se creó correctamente. Elija el código de error más apropiado si no lo era.

Por ejemplo, si proporciona una API para crear registros de empleados, la solicitud / respuesta podría tener este aspecto:

POST /employees HTTP/1.1
Host: example.com
Content-Type: application/json

{
    "name": "Charlie Smith",
    "age": 38,
    "job_title": "Software Developer",
    "salary": 54895.00
}
HTTP/1.1 201 Created
Location: /employees/1/charlie-smith
Content-Type: application/json

{
    "employee": {
        "name": "Charlie Smith",
        "age": 38,
        "job_title": "Software Developer",
        "salary": 54895.00
        "links": [
            {
                "uri": "/employees/1/charlie-smith",
                "rel": "self",
                "method": "GET"
            },
            {
                "uri": "/employees/1/charlie-smith",
                "rel": "delete",
                "method": "DELETE"
            },
            {
                "uri": "/employees/1/charlie-smith",
                "rel": "edit",
                "method": "PATCH"
            }
        ]
    },
    "links": [
        {
            "uri": "/employees",
            "rel": "create",
            "method": "POST"
        }
    ]
}

La inclusión de los campos JSON de links en la respuesta permite al cliente acceder al recurso relacionado con el nuevo recurso y con la aplicación en su conjunto, sin tener que conocer sus URI o métodos de antemano.

Editar un recurso

Editar o actualizar un recurso es un propósito común de las API. Las ediciones se pueden lograr mediante el envío de POST , PUT o PATCH al recurso respectivo. Aunque POST tiene permitido agregar datos a la representación existente de un recurso, se recomienda usar PUT o PATCH ya que transmiten una semántica más explícita.

Su servidor debe responder con 200 OK si se realizó la actualización, o 202 Accepted si aún no se ha aplicado. Elija el código de error más apropiado si no se puede completar.

Actualizaciones completas

PUT tiene la semántica de reemplazar la representación actual con la carga útil incluida en la solicitud. Si la carga útil no es del mismo tipo de representación que la representación actual del recurso a actualizar, el servidor puede decidir qué enfoque tomar. RFC7231 define que el servidor puede:

  • Reconfigure el recurso de destino para reflejar el nuevo tipo de medio
  • Transforme la representación PUT a un formato consistente con el del recurso antes de guardarlo como el nuevo estado de recurso
  • Rechace la solicitud con una respuesta de 415 Unsupported Media Type que indique que el recurso de destino está limitado a un determinado (conjunto) de tipos de medios.

Un recurso base que contiene una representación JSON HAL como ...

{
    "name": "Charlie Smith",
    "age": 39,
    "job_title": "Software Developer",
    "_links": {
        "self": { "href": "/users/1234" },
        "employee": { "href": "http://www.acmee.com" },
        "curies": [{ "name": "ea", "href": "http://www.acmee.com/docs/rels/{rel}", templated": true}],
        "ea:admin": [
            "href": "/admin/2",
            "title": "Admin"
        ]
    }
}

... puede recibir una solicitud de actualización como esta

PUT /users/1234 HTTP/1.1
Host: http://www.acmee.com
Content-Type: "application/json; charset=utf-8"
Content-Length: 85
User-Agent: Mozilla/4.0 (compatible; MSIE5.01; Windows NT)

{
    "name": "Charlie Gold-Smith",
    "age": 40,
    "job_title": "Senior Software Developer"
}

El servidor ahora puede reemplazar el estado del recurso con el cuerpo de solicitud dado y también cambiar el tipo de contenido de application/hal+json a application/json o convertir la carga útil JSON en una representación JSON HAL y luego reemplazar el contenido del recurso con la transformada o rechace la solicitud de actualización debido a un tipo de medio inaplicable con una respuesta de 415 Unsupported Media Type .

Hay una diferencia entre reemplazar el contenido directamente o primero transformar la representación en el modelo de representación definido y luego reemplazar el contenido existente con el transformado. Una solicitud GET posterior devolverá la siguiente respuesta en un reemplazo directo:

GET /users/1234 HTTP/1.1
Host: http://www.acmee.com
Accept-Encoding: gzip, deflate
Accept-Language: en-us
User-Agent: Mozilla/4.0 (compatible; MSIE5.01; Windows NT)
ETag: "e0023aa4e"

{
    "name": "Charlie Gold-Smith",
    "age": 40,
    "job_title": "Senior Software Developer"
}

mientras que el enfoque de transformación y luego reemplazo devolverá la siguiente representación:

GET /users/1234 HTTP/1.1
Host: http://www.acmee.com
Accept-Encoding: gzip, deflate
Accept-Language: en-us
User-Agent: Mozilla/4.0 (compatible; MSIE5.01; Windows NT)
ETag: e0023aa4e

{
    "name": "Charlie Gold-Smith",
    "age": 40,
    "job_title": "Senior Software Developer",
    "_links": {
        "self": { "href": "/users/1234" },
        "employee": { "href": "http://www.acmee.com" },
        "curies": [{ "name": "ea", "href": "http://www.acmee.com/docs/rels/{rel}", templated": true}],
        "ea:admin": [
            "href": "/admin/2",
            "title": "Admin"
        ]
    }
}

Efectos secundarios

Tenga en cuenta que PUT puede tener efectos secundarios, aunque se define como una operación idempotente. Esto está documentado en RFC7231 como

Una solicitud PUT aplicada al recurso de destino puede tener efectos secundarios en otros recursos . Por ejemplo, un artículo puede tener un URI para identificar "la versión actual" (un recurso) que es independiente de los URI que identifican cada versión en particular (diferentes recursos que en un punto compartían el mismo estado que el recurso de la versión actual). Por lo tanto, una solicitud PUT exitosa en el URI de "la versión actual" podría crear un nuevo recurso de versión además de cambiar el estado del recurso de destino, y también podría ocasionar que se agreguen enlaces entre los recursos relacionados.

La producción de entradas de registro adicionales no se considera un efecto secundario, ya que este no es un estado de un recurso en general.

Actualizaciones parciales

RFC7231 menciona esto con respecto a actualizaciones parciales:

Las actualizaciones parciales de contenido son posibles al apuntar a un recurso identificado por separado con un estado que se superpone a una parte del recurso más grande, o al usar un método diferente que se haya definido específicamente para actualizaciones parciales (por ejemplo, el método PATCH definido en RFC5789 ).

Por lo tanto, las actualizaciones parciales se pueden realizar en dos sabores:

  • Haga que un recurso incruste múltiples sub-recursos más pequeños y actualice solo un sub-recurso respectivo en lugar del recurso completo a través de PUT
  • Usando PATCH e instruir al servidor que actualizar

Actualización parcial con estado superpuesto

Si una representación de usuario necesita actualizarse parcialmente debido a un traslado de un usuario a otra ubicación, en lugar de actualizar al usuario directamente, el recurso relacionado debe actualizarse directamente, lo que se refleja en una actualización parcial de la representación del usuario.

Antes de la mudanza un usuario tenía la siguiente representación.

GET /users/1234 HTTP/1.1
Host: http://www.acmee.com
Accept: application/hal+json; charset=utf-8
Accept-Encoding: gzip, deflate
Accept-Language: en-us
User-Agent: Mozilla/4.0 (compatible; MSIE5.01; Windows NT)
ETag: "e0023aa4e"

{
    "name": "Charlie Gold-Smith",
    "age": 40,
    "job_title": "Senior Software Developer",
    "_links": {
        "self": { "href": "/users/1234" },
        "employee": { "href": "http://www.acmee.com" },
        "curies": [{ "name": "ea", "href": "http://www.acmee.com/docs/rels/{rel}", templated": true}],
        "ea:admin": [
            "href": "/admin/2",
            "title": "Admin"
        ]
    },
    "_embedded": {
        "ea:address": {
            "street": "Terrace Drive, Central Park",
            "zip": "NY 10024"
            "city": "New York",
            "country": "United States of America",
            "_links": {
                "self": { "href": "/address/abc" },
                "google_maps": { "href": "http://maps.google.com/?ll=40.7739166,-73.970176" }
            }
        }
    }
}

Cuando el usuario se está moviendo a una nueva ubicación, actualiza la información de su ubicación de esta manera:

PUT /address/abc HTTP/1.1
Host: http://www.acmee.com
Content-Type: "application/json; charset=utf-8"
Content-Length: 109
User-Agent: Mozilla/4.0 (compatible; MSIE5.01; Windows NT)

{
    "street": "Standford Ave",
    "zip": "CA 94306",
    "city": "Pablo Alto",
    "country": "United States of America"
}

Con la transformación antes de reemplazar la semántica para el tipo de medio no coincidente entre el recurso de dirección existente y el que está en la solicitud, como se describió anteriormente, el recurso de dirección ahora se actualiza, lo que tiene el efecto que en una solicitud GET posterior en el recurso de usuario Se devuelve la nueva dirección para el usuario.

GET /users/1234 HTTP/1.1
Host: http://www.acmee.com
Accept: application/hal+json; charset=utf-8
Accept-Encoding: gzip, deflate
Accept-Language: en-us
User-Agent: Mozilla/4.0 (compatible; MSIE5.01; Windows NT)
ETag: "e0023aa4e"

{
    "name": "Charlie Gold-Smith",
    "age": 40,
    "job_title": "Senior Software Developer",
    "_links": {
        "self": { "href": "/users/1234" },
        "employee": { "href": "http://www.acmee.com" },
        "curies": [{ "name": "ea", "href": "http://www.acmee.com/docs/rels/{rel}", templated": true}],
        "ea:admin": [
            "href": "/admin/2",
            "title": "Admin"
        ]
    },
    "_embedded": {
        "ea:address": {
            "street": "Standford Ave",
            "zip": "CA 94306",
            "city": "Pablo Alto",
            "country": "United States of America"
            "_links": {
                "self": { "href": "/address/abc" },
                "google_maps": { "href": "http://maps.google.com/?ll=37.4241311,-122.1524475" }
            }
        }
    }
}

Parcheando datos parciales

PATCH se define en RFC5789 y no forma parte directamente de la especificación de HTTP per se. Un error común es que enviar solo los campos que deben actualizarse parcialmente es suficiente dentro de una solicitud de PATCH . Por lo tanto, la especificación establece

El método PATCH solicita que un conjunto de cambios descritos en la entidad de solicitud se aplique al recurso identificado por el URI de solicitud. El conjunto de cambios se representa en un formato denominado "documento de revisión" identificado por un tipo de medio.

Esto significa que un cliente debe calcular los pasos necesarios necesarios para transformar el recurso del estado A al estado B y enviar estas instrucciones al servidor.

Un tipo de medio popular basado en JSON para la aplicación de parches es JSON Patch .

Si la edad y el título del trabajo de nuestro usuario de muestra cambian y se debe agregar un campo adicional que represente los ingresos del usuario, se debe agregar una actualización parcial utilizando PATCH utilizando el parche JSON:

PATCH /users/1234 HTTP/1.1
Host: http://www.acmee.com
Content-Type: application/json-patch+json; charset=utf-8
Content-Length: 188
Accept: application/json
If-Match: "e0023aa4e"

[
    { "op": "replace", "path": "/age", "value": 40 },
    { "op": "replace", "path": "/job_title", "value": "Senior Software Developer" },
    { "op": "add", "path": "/salery", "value": 63985.00 }
]

PATCH puede actualizar múltiples recursos a la vez y requiere aplicar los cambios de forma atómica, lo que significa que se deben aplicar todos los cambios o ninguno en absoluto, lo que supone una carga transaccional para el implementador de la API.

Una actualización exitosa puede devolver algo como esto

HTTP/1.1 200 OK
Location: /users/1234
Content-Type: application/json
ETag: "df00eb258"

{
    "name": "Charlie Smith",
    "age": 40,
    "job_title": "Senior Software Developer",
    "salary": 63985.00
}

aunque no está restringido a 200 OK códigos de respuesta 200 OK solamente.

Para evitar las actualizaciones intermedias (los cambios realizados entre la recuperación previa del estado de representación y la actualización) se deben utilizar los encabezados ETag , If-Match o If-Unmodified-Since .

Manejo de errores

La especificación en PATCH recomienda el siguiente manejo de errores:

Tipo Código de error
Documento de parche mal formado 400 Bad Request
Documento de parche no admitido 415 Unsupported Media Type
Solicitud no procesable, es decir, si el recurso se vuelve inválido al aplicar el parche 422 Unprocessable Entity
Recurso no encontrado 404 Not Found
Estado conflictivo, es decir, un cambio de nombre (movimiento) de un campo que no existe 409 Conflict
Modificación conflictiva, es decir, si el cliente utiliza un encabezado If-Match o If-Unmodified-Since cuya validación falló. Si no se dispone de una condición previa, se debe devolver el último código de error 412 Precondition Failed o 409 Conflict
Modificación concurrente, es decir, si la solicitud debe aplicarse antes de la aceptación, más solicitudes de PATCH 409 Conflict

Eliminar un recurso

Otro uso común de las API de HTTP es eliminar un recurso existente. Esto usualmente se debe hacer usando las solicitudes DELETE .

Si la eliminación fue exitosa, el servidor debería devolver 200 OK ; un código de error apropiado si no lo era.

Si nuestro empleado Charlie Smith ha dejado la empresa y ahora queremos eliminar sus registros, podría tener este aspecto:

DELETE /employees/1/charlie-smith HTTP/1.1
Host: example.com
HTTP/1.1 200 OK
Content-Type: application/json

{
    'links': [
        {
            'uri': '/employees',
            'rel': 'create',
            'method': 'POST'
        }
    ]
}

Lista de recursos

El último uso común de las API de HTTP es obtener una lista de los recursos existentes en el servidor. Las listas de este tipo deben obtenerse utilizando solicitudes GET , ya que solo recuperan datos.

El servidor debe devolver 200 OK si puede suministrar la lista, o un código de error apropiado si no lo hace.

Listado de nuestros empleados, entonces, podría verse así:

GET /employees HTTP/1.1
Host: example.com
HTTP/1.1 200 OK
Content-Type: application/json

{
    'employees': [
        {
            'name': 'Charlie Smith',
            'age': 39,
            'job_title': 'Software Developer',
            'salary': 63985.00
            'links': [
                {
                    'uri': '/employees/1/charlie-smith',
                    'rel': 'self',
                    'method': 'GET'
                },
                {
                    'uri': '/employees/1/charlie-smith',
                    'rel': 'delete',
                    'method': 'DELETE'
                },
                {
                    'uri': '/employees/1/charlie-smith',
                    'rel': 'edit',
                    'method': 'PATCH'
                }
            ]
        },
        {
            'name': 'Donna Prima',
            'age': 30,
            'job_title': 'QA Tester',
            'salary': 77095.00
            'links': [
                {
                    'uri': '/employees/2/donna-prima',
                    'rel': 'self',
                    'method': 'GET'
                },
                {
                    'uri': '/employees/2/donna-prima',
                    'rel': 'delete',
                    'method': 'DELETE'
                },
                {
                    'uri': '/employees/2/donna-prima',
                    'rel': 'edit',
                    'method': 'PATCH'
                }
            ]
        }
    ],
    'links': [
        {
            'uri': '/employees/new',
            'rel': 'create',
            'method': 'PUT'
        }
    ]
}


Modified text is an extract of the original Stack Overflow Documentation
Licenciado bajo CC BY-SA 3.0
No afiliado a Stack Overflow