Está en la página 1de 36

Guía de diseño de la

API REST WSO2

Sobre este eBook:

Este ebook es una traducción y adaptación del contenido orginal de WSO2


“WSO2 Rest API Design Guidelines”
Índice

1. Introducción 4

2. Enfoque global 5

3. El modelo de datos 6

4. El modelo de recursos 7

4.1 Recursos atómicos (Atomic resources) 7


4.2 Recursos de recolección (Collection resources) 7
4.3 Recursos compuestos (Composite resources) 7
4.4 Recursos del controlador (Controller resources) 8
4.5 Recursos de la función de procesamiento
(Processing Function Resources) 8
4.6 Relaciones de interpretación 9

5. Recursos URIs 10

5.1 Nombrar de forma adecuada 10


5.2 Esquemas 11
5.3 Host 11
5.4 Ruta base 11
5.5 Versionar 11
5.6 Plantillas URI 12
5.7 Cadena de consulta (Query String) 13

6. Especificación de representación 14

7. Los métodos HTTP usados 15

7.1 GET 15
7.2 PUT 15
7.3 POST 16
7.4 DELETE 16

www.chakray.com 2
8. Encabezados 17

8.1 Encabezados de solicitudes (Request Headers) 17


8.2 Encabezados de respuesta (Response Headers)) 18

9. Códigos de estatus (Status Codes) 19

10. Comportamiento especial 21

10.1 Negociación de contenido 21


10.2 Consultas 22
10.3 Paginación 23
10.4 Almacenamiento cache en el lado del cliente 24
10.5 Control de concurrencia 25
10.6 Peticiones largas 26

11. Reporte de errores 29

12. Seguridad 30

12.1 Base de la autenticación 30


12.2 Autorización abierta (OAuth) 31
12.3 eXtensible Access Control Markup Language (XACML) 31

13. Referencias 33

Sobre el autor y el traductor 34

www.chakray.com 3
1. Introducción

Siguiendo las indicaciones contenidas en este documento la API resultante


alcanzará el Nivel 1 del modelo de madurez de Richardson (Richadson Ma-
turity model) ([1], [4]). Esto implicará la provisión de un modelo de recursos,
la implementación de un método HTTP(S) adecuado, la identificación del uso
adecuado de los encabezados HTTP y aplicación de los códigos de estado de
HTTP en respuestas.

El nivel superior – Nivel 3- del modelo de madurez de Richardson no será


alcanzado. Este tercer nivel implica hacer uso de controles hipermedia: este
tipo de controles permiten a los servidores REST informar a los clientes
REST sobre las API que deben ser invocadas en el estado actual de la aplica-
ción. Aunque esto pueda resultar muy prometedor en términos, por ejemplo,
de mantenimiento (ej. la API se cambia sin que los clientes tengan que enten-
der esos cambios), todavía no se han consolidado unas buenas prácticas para
poder trabajar con ello.

www.chakray.com 4
2. Enfoque global

Para crear una API REST (nivel 2) se deben seguir estos pasos principales:

Figura 1: Método de diseño de una API REST.

Primero, se tiene que crear el modelo de datos que van a ser manipulados por la API. Desde
este modelo de datos se tendrán que determinar los recursos que se van a usar para la API;
normalmente no hay una relación exacta entre los elementos del modelo de datos y los
recursos de la API, sobre todo porque normalmente se derivan nuevos tipos de recursos.
Tienen que determinarse para cada uno de los recursos las representaciones soportadas
por la API. Lo siguiente es que estos recursos se nombren adecuadamente con URIs (Uni-
form Resource Identifiers). Para cada uno de los recursos tienen que decidirse el método
HTTP utilizado para realizar las funciones de la aplicación. Esto incluye el uso de la aplica-
ción de los encabezados HTTP. El comportamiento especial requerido por la aplicación (ej.
control de concurrencia, solicitudes largas) tiene que decidirse también. Finalmente, han
de identificarse las potenciales situaciones de error y diseñar los correspondientes men-
sajes de error.

Nota: Aunque la figura 1 dibuja el enfoque como uno proceso secuencial, no siempre es
necesario seguirlo paso por paso. Por ejemplo:

• Puede que el modelo de datos ya se conozca. En este caso se omitirá el primer paso

• Si el modelo de recursos ya ha sido decidido, también puede saltarse ese segundo paso.
Pero en el caso de que no esté completamente especificado, merecerá la pena hacer el
paso 1.

• Si tu API es muy sencilla, por ejemplo, no busca actualizaciones concurrentes de tus re-
cursos o no inicia acciones de larga duración, entonces puedes ir directamente al paso de
determinar el comportamiento especial.

Cada uno de los pasos de este enfoque global se detallarán en las siguientes secciones.

www.chakray.com 5
3. El modelo de datos

El modelo de datos que hay tras una API puede ser especificado por cualquier lenguaje de
modelado de datos, como el modelo entidad-relación (E-R) o el diagrama de clases UML.
De ahora en adelante, asumiremos que se ha optado por el modelo entidad-relación.

La principal finalidad del modelo de datos tras la API es especificar las propiedades de los
recursos que serán manipulados por la API de forma abstracta (ej. implementación inde-
pendiente). Especificando los atributos de los tipos de entidades del modelo de dato no
se está tomando una decisión temprana sobre el formato y el tipo de medio en el que las
instancias de los tipos de entidad (también conocidas como representaciones en REST) ​​se
intercambian, esta decisión se tomará después, y puede cambiarse en cualquier momento.
Sin embargo, de este modo el proceso de desarrollo es más flexible.

Figura 2: Ejemplo de modelo de datos.

La figura 2 muestra un ejemplo de modelo de datos que va a usarse en las siguientes seccio-
nes para mostrar cómo aplicar las indicaciones dadas.

El modelo de datos es una importante fuente para determinar un adecuado modelo de re-
cursos. Sin embargo, el modo en el que los clientes interactúan con la API tiene una gran
influencia en el modelo de recursos que se deriva del modelo de datos (“el cliente gana
sobre los datos”). El modelo de dominios dirige la implementación de la API, mientras que
el modelo de recursos es dirigido por las interacciones del cliente. No obstante, lo normal
es que el modelo de recursos “siga el modelo de datos”.

www.chakray.com 6
4. El modelo de recursos

El modelo de recursos especifica los recursos que son procesados por la API. Algunos tipos
de recursos se derivarán del modelo de datos, así como de los requerimientos del proceso
de correspondencia.

4.1 Recursos atómicos (Atomic resources)


La decisión más básica que se ha de tomar para derivar recursos es identificar las entidades
del modelo de datos que van a ser intercambiadas en su conjunto a través de la API. Estas
entidades se convierten en recursos atómicos.

Por ejemplo, siguiendo el ejemplo de modelo de datos de la figura 2, la entidad “cliente” es


una entidad atómica. Esto se debe a que se va acceder a los detalles sobre el cliente como
su dirección, la información de pago y demás en distintos escenarios a través de la API.

4.2 Recursos de recolección (Collection resources)


La siguiente decisión a tomar es si los distintos recursos atómicos son susceptibles de ser
agrupados en un set. Estos grupos se convierten en recursos de recolección.

Por ejemplo, los productos son un recurso de recolección porque la aplicación tira de un
catálogo que permite navegar a través de todos los productos disponibles. Nótese que
no hay un tipo de entidad “productos” dentro del modelo de datos. Debido a que la apli-
cación requiere de estos recursos de recolección, tendremos que derivarlos del modelo
de datos dándoles uno nuevo nombre que corresponda con el plural de los nombres de
la entidad agrupada.

Como otro ejemplo también tenemos los ‘Artículos’, que se convierten en un recurso de
recolección que representan todos los artículos contenidos en el carrito de la compra de
un determinado cliente. Esta colección tendrá un alcance, pues solo interesan los artículos
de un determinado carrito de compra, y no el conjunto de todos los artículos en todos los
carritos de compras (véase sección 5.6 para más detalle sobre el alcance).

Por último, siempre que la API admita la creación de una instancia de uno de los tipos de
entidades del modelo de datos, este tipo de entidad generará el recurso de recopilación
correspondiente. Por ejemplo, un nuevo cliente puede registrarse con la aplicación dando
como resultado una nueva instancia del tipo de entidad Cliente. Por lo tanto, los clientes se
convertirán en un recurso de recopilación.

4.3 Recursos compuestos (Composite resources)


A veces, las instancias de grupos de diferentes tipos de entidades se manipulan en su
conjunto porque estas instancias se perciben como agregados, ya que, por ejemplo,
normalmente se recuperan o eliminan colectivamente. Tales grupos se convierten en
recursos compuestos.

www.chakray.com 7
Así, el carrito de compras es un recurso compuesto, ya que a menudo se recupera o se eli-
mina en su conjunto, es decir, con todos los elementos incluidos.

4.4 Recursos del controlador (Controller resources)


Los recursos del controlador se utilizan cuando se deben manipular múltiples recursos en
una sola llamada de API para mantener la coherencia de los datos. Si las reglas de integri-
dad entre los recursos deben ser obedecidas, el cliente tendría que entender estas reglas
como el orden en el cual los recursos deben ser manipulados. Proporcionar un recurso de
controlador para manipular estos recursos en una única llamada de API evita que el cliente
tenga que entender estas reglas - una contribución significativa al acoplamiento suelto.

Por ejemplo, ir eliminando individualmente los elementos del carrito de compra puede dar
problemas de consistencia en caso de que se produzca un error después de haber elimina-
do sólo los primeros elementos, mientras otros quedan en el carrito. Así, el cliente que de-
mande el carrito de la compra en este momento del error se encontrará con que su carrito
se ha “roto”.

Otro ejemplo es la actualización de dos recursos de cuentas para realizar una transferencia
de dinero -la motivación clásica para las transacciones de ACID (Atomicidad, Consistencia,
Aislamiento, Durabilidad). Cada una de estas dos cuentas es un recurso atómico, es decir,
los recursos del controlador son cosas diferentes que los recursos compuestos.

4.5 Recursos de la función de procesamiento (Processing Function


Resources)
Los recursos de la función de procesamiento (también conocidos como recursos de cóm-
puto) proporcionan acceso a funciones que procesan recursos particulares o que reali-
zan determinados cálculos independientes de recursos. En la práctica, los recursos de la
función de procesamiento se usan a menudo para actualizaciones parciales predefinidas
de un recurso.

Por ejemplo, cambiar el estado de un recurso como el precio de un producto u obtener el


porcentaje oficial de cambio entre dos monedas distintas puede realizarse a través de los
recursos con función de procesamiento.

Nota: Las actualizaciones parciales están dirigidas por el método HTTP PATCH [7]. El pro-
blema que tiene PATCH es doble:

01 El método PATCH (todavía) no es soportado por todos los servidores web. Por
supuesto, este problema se resolverá.

02 La sintaxis y semántica para cada uno de los usos del método PATCH tiene que
definirse claramente:

www.chakray.com 8
El recurso encerrado en el cuerpo del método PATCH es un documento de instrucciones,
es decir, un conjunto de instrucciones que describen con precisión lo que se tiene que
actualizar y cómo, y todas estas instrucciones deben realizarse de forma atómica. Espe-
cialmente, el tipo de medio de este documento de instrucción es típicamente diferente
del tipo de medio del recurso que va a ser modificado por el PATCH. El documento de
instrucción puede ser percibido como una especie de transacción sobre el recurso que
se va a manipular.

Esto da como resultado la amplia explotación de los recursos de la función de procesamien-


to para realizar estas actualizaciones parciales.

4.6 Relaciones de interpretación


Uno de los principales problemas de derivar un modelo de recursos de un modelo de datos
es la interpretación de las relaciones entre los tipos de entidades del modelo de datos.

Si la manipulación de instancias de un determinado tipo de entidad no requiere el recorrido


de sus relaciones asociadas, entonces tal tipo de entidad es un candidato para un recurso
atómico: si las instancias tienen que estar disponibles a través de la API, el tipo de entidad
se transforma en un recurso atómico en una correspondencia uno-uno.

Los recursos de recolección pueden estar sujetos a una interpretación de sus tipos de re-
lación asociados, es decir, las colecciones sólo pueden tener sentido como hijos de otros
recursos (las denominadas colecciones con alcance, véase 5.6).

Por ejemplo: el recurso de recolección de ‘Productos’ no tiene alcance, es decir, esta co-
lección es un recurso de primera clase del modelo de recurso de nuestro ejemplo. En
contraste con esto, el recurso de recolección de ‘Artículos’ sí que tiene alcance: la colec-
ción de todos los artículos en todos los carros de la compra no es lo que normalmente
interesa, sino que lo que interesa son todos los artículos de un determinado carrito de
compra. Por lo tanto, las colecciones de elementos que dependen de un determinado ca-
rrito de compra son un recurso de recolección (véase la sección 5.6 cómo denotar dichas
colecciones con alcance).

Si la API tiene que soportar la creación directa de instancias de un tipo de entidad, este tipo
de entidad resulta en un recurso de recolección. Esto se debe a que en el paradigma REST un
recurso de recolección es una fábrica para sus miembros (ver sección 7.3). El tipo de entidad
en sí es la base de los recursos atómicos que son los miembros del recurso de recolección.

Los recursos de la función de procesamiento, así como los recursos del controlador, resul-
tan de los requisitos funcionales: normalmente no se derivan inmediatamente del modelo
de datos, sino de los requisitos de actualización o de los requisitos para derivar informa-
ción que puede que no esté siquiera relacionada con otros recursos.

www.chakray.com 9
5. Recursos URIs

La identificación de recursos URI de una API sigue la siguiente estructura:

{scheme}://{host}/{base-path}/{path}[?{query-string}]1, 2

Las siguientes secciones explicarán la siguiente estructura.

5.1 Nombrar de forma adecuada


El nombramiento adecuado de los recursos es clave para que la API sea fácilmente enten-
dible por los clientes. Existen algunas reglas que deben seguirse ([2], [3], [5]):

• Los recursos atómicos, los recursos de recolección y los recursos compuestos deben
ser identificados con nombres porque representan “cosas” no “acciones” (las acciones
tienden a nombrarse con verbos en los recursos)

• Los recursos de la función de procesamiento y los recursos del controlador deberían


nombrarse con verbos ya que representan “acciones”.

• Los recursos de la función de procesamiento y los recursos del controlador no deberían


ser sub-recursos de otro recurso individual
- No deben ser nombrados por medio de una plantilla URI (ver 5.6).
- Los recursos individuales se convierten en parámetros

• Para los nombres deberían usarse los únicamente caracteres en minúscula, ya que las
reglas sobre qué nombres USI son sensibles a mayúsculas y minúsculas, y cuáles no, pue-
den dar lugar a confusión.

• Si se usan múltiples palabras para nombrar un recurso, hay que separar estas palabras
con guion medio.
- No se debería usar el guion bajo cuando: los nombres van a ser interpretados por
los buscadores, pues se entenderán como enlaces y serán difícil de leer.
- Del mismo modo, CamelCase (DbmXmlFromIPAddress) u otros lenguajes de pro
gramación en lo relativo a nombrar deben ser evitados

• Para nombrar recursos atómicos deberían usarse nombres en singular

• Los nombres de las colección deberían nombrarse en plural, es decir, por el nombre en
plural de los conceptos agrupados (los recursos atómicos o compuestos)

• Usa la barra inclinada (/) para especificar la relación de jerarquía entre recursos. La ba-
rra inclinada separará los nombres de los recursos estructurados jerárquicamente. El
nombre del padre estará seguido del nombre de su hijo más inmediato.

www.chakray.com 10
5.2 Esquemas
Un esquema denota el protocolo de transporte soportado por la API. Normalmente, las
API de WSO2 serán accesibles a través de HTTPS, algunas API pueden soportar HTTP y
algunas pueden admitir ambos esquemas.

5.3 Host
La parte del host de la API especifica el dominio de la API. Para las API alojadas en WSO2,
este valor es apis.wso2.com. Cuando esté alojada por o para los clientes esto será sustitui-
do por la serie específica del cliente.

5.4 Ruta base


La ruta base de una API sigue la siguiente estructura

/{feature-code}/[ {sub-code}/ ]/{version}

Por lo tanto, cada ruta base consta de una estructura de código caracterizada que indica
la característica para la que es esta API. Se puede utilizar una estructura de subcódigo op-
cional para entidades que contienen colecciones de funcionalidades lógicamente indepen-
dientes. Por ejemplo, el código caracterizado puede ser “apim” para el Administrador de la
API, en cuyo caso no se utiliza ningún subcódigo, y la versión puede ser v1.0 (ver sección
5.5 para más detalles sobre el control de versiones). Para Enterprise Store, la caracteriza-
ción del código puede ser “es” y la funcionalidad independiente de Publisher puede tener
asignado el subcódigo “publicador”.

La ruta base será la misma para todas las API de ciertas características o colecciones lógica-
mente independientes de funcionalidades con características comunes, respectivamente.
Esta ruta base precederá a cada nombre de recurso propio de la API, es decir, al elemento
de ruta de acceso del URI de la API. Tenga en cuenta que una ruta se codifica a menudo
como una plantilla de URI (consulte la sección 5.6).

5.5 Versionar
Una versión de una API se especifica como parte de su URI. Esta versión se especifica con
dos números enteros (separados por un punto) denominados el número mayor y el menor
de la versión, precedidos por la letra minúscula “v”. Por ejemplo una serie de versión válida
en la ruta base sería v2.1, que indica que es la primera versión de la segunda versión de la
API correspondiente.

El uso de este esquema de versiones se conoce como versionamiento semántico [6]. En ge-
neral, un número de versión que siga el concepto de versión semántica tiene la estructura
major.minor.patch y la importancia en términos de impacto del cliente va aumentando de
izquierda a derecha:

www.chakray.com 11
• Un número de parche incrementado significa que la modificación subyacente a la API no
puede siquiera ser percibida por un cliente - por lo tanto, el número de parche se omite
de la serie de versión. Sólo se ha modificado la implementación interna de la API mien-
tras que la firma de la API no ha cambiado. Desde la perspectiva del desarrollador de
la API, un nuevo número de parche indica una corrección de errores, una modificación
interna menor, etc.

• Un número menor incrementado indica que se han agregado nuevas características a


la API, pero esta adición debe ser compatible con versiones anteriores: el cliente puede
utilizar la API antigua sin fallar. Por ejemplo, la API puede agregar nuevos parámetros
opcionales o una solicitud completamente nueva.

• Un número mayor incrementado señala cambios que no son compatibles con versio-
nes anteriores: por ejemplo, se han agregado nuevos parámetros obligatorios, se han
eliminado los parámetros anteriores o las solicitudes anteriores completas ya no están
disponibles.

La mejor práctica es soportar tanto la versión principal actual como por lo menos una ver-
sión por detrás. En el caso de que se creen nuevas versiones frecuentemente (por ejemplo,
cada pocos meses), debería haber más versiones principales compatibles. De lo contrario,
los clientes se te caerán (demasiado rápido).

Cuando un cliente está usando el URI de una API con un número de versión que ya no es
compatible, el servidor tiene que responder con el siguiente mensaje de respuesta, que
contiene expresamente una encabezado de ubicación con el URI de la última versión de
la API:

HTTP/1.1 301 Moved Permanently


Location:

Nota: Existe mucho debate sobre cómo especificar versiones y hay un par de enfoques al-
ternativos sobre esta área. La discusión abarca todo el espectro desde lo que el estilo REST
puro considera como un recurso a lo que ofrecen los grandes proveedores de API web. Lo
que se recomienda aquí es una guía pragmática.

5.6 Plantillas URI


Una plantilla URI es un elemento que contiene series entre corchetes [8]. Estas series son
variables que deben ser sustituidas por valores cuando dicha plantilla URI es utilizada por
un cliente.

Por ejemplo, cuando uses la plantilla URI

/shopping-carts/{shopping-cart-id}/{item-id}/product

www.chakray.com 12
“shopping-cart-id” y “item-id” son variables. Estas variables tienen que ser sustituidas
cuando se use una API que usa esta plantilla URI en su ruta.

Un uso típico de las plantillas de URI está en los recursos de recolección. Un miembro indi-
vidual de la colección será identificado por un valor único, que se convertirá en la variable
en la plantilla que va inmediatamente después del nombre del recurso de recolección co-
rrespondiente. Por ejemplo:

/products/{product-id}

Obsérvese la diferencia entre esta plantilla URI y la anterior. Esta plantilla de URI denota
una colección que se deriva inmediatamente de un tipo de entidad del modelo de datos.
Todas las instancias de este tipo de entidad deben ser accesibles desde la API, y se agrupan
en la colección para ese propósito.

La plantilla URI anterior es diferente en el sentido de que se ha abstraído de un tipo de re-


lación del modelo de datos, es decir, la relación entre el tipo de entidad ‘Carrito de compra’
y el tipo de entidad ‘Artículo’. Dado que no es necesario acceder al conjunto de todas las
instancias del tipo de entidad ‘Artículo’, ningún tipo de colección de elementos dedicados
forma parte del modelo de recurso. En cambio, sólo los elementos asociados con un de-
terminado carrito de compras (identificados por su ID de carrito de compras) deben ser
accesibles por la API, es decir, este conjunto de elementos está delimitado por el carrito
de compra correspondiente: la colección de elementos se denomina colección de alcance.

5.7 Cadena de consulta (Query String)


Por definición, una cadena de consulta opcional (si se especifica) es una parte de la URI que
contribuye a la identificación única de un recurso. Es decir, el URI sin la cadena de consulta
y el URI con la cadena de consulta identifican diferentes recursos (un hecho que a menudo
se ignora).

Sin embargo, es recomendable no utilizar campos de la cadena de consulta como compo-


nentes de identificación. En este sentido, una cadena de consulta proporciona parámetros
para controlar la ejecución de la API que procesa el recurso identificado por la estructura
que precede al símbolo “?”:

{scheme}://{host}/{base-path}/{path}?{query-string}

La cadena de consulta consta de una secuencia de pares nombre /valor que están separa-
dos por una “&”. La cadena de nombres y la cadena de valores están separados por un “=”.
En la práctica, los URIs son de tamaño limitado. Aún peor, el tamaño máximo soportado
por los productos difiere. Como consecuencia, los parámetros de las cadenas de consulta
grandes deben moverse al cuerpo del mensaje de las solicitudes correspondientes. Tenga
en cuenta que esto sólo funcionará para las solicitudes que permiten un cuerpo de mensaje
(especialmente POST, pero no GET).

www.chakray.com 13
6. Especificación de representación

Un formato en el que se intercambian instancias de los tipos de entidad del modelo de da-
tos se denomina como representación de esa instancia. Una representación es una especie
de forma de un recurso, no el recurso en sí. En este sentido, una representación es una
especie de vista sobre el recurso.

El contenido de información de un recurso atómico o de un recurso compuesto está in-


mediatamente definido por el modelo de datos que subyace a la API. Los valores de los
atributos y, en su caso, los identificadores de recursos asociados constituyen el contenido
de información de un recurso atómico. De manera similar, el agregado de los contenidos de
información de los recursos de un recurso compuesto es el contenido de información del
recurso compuesto.

Se debe decidir una estructura de datos para este contenido de información. Además, tam-
bién debe decirse una o más representaciones de esta estructura de datos. Por ejemplo,
una determinada estructura de datos se puede representar como un documento JSON
(Object Object Notation) o XML (eXtensible Markup Language). Normalmente, las repre-
sentaciones de estructuras de datos se especifican por medio de tipos MIME (Multipur-
pose Internal Mail Extensions). Una representación específica de una estructura de datos
se denomina representación del recurso, es decir, una representación tiene un tipo MIME.
Tenga en cuenta que este tipo MIME no indica la estructura de datos de la información
intercambiada entre el cliente y la implementación de la API, sino sólo la representación.

Nota: En la práctica, normalmente es suficiente una sola representación (por ejemplo,


JSON) para todas las entidades intercambiadas a través de una API.

www.chakray.com 14
7. Los métodos HTTP usados

La manipulación de recursos en el estilo REST se realiza mediante operaciones de creación,


recuperación, actualización y supresión (llamadas operaciones CRUD), que asignan a los
métodos HTTP POST, GET, PUT y DELETE.

Una solicitud que se puede utilizar sin producir ningún efecto secundario se llama una so-
licitud segura. Una petición que se puede utilizar varias veces y que siempre produce el
mismo efecto que la primera invocación se conoce como idempotente.

7.1 GET
GET está en HTTP, así como en el estilo REST especificado como una solicitud segura e
idempotente. Por lo tanto, una API que utiliza el método GET no debe producir ningún efec-
to secundario. Recuperar un recurso atómico (4.1) o un recurso compuesto (4.3) se realiza
mediante la realización de un GET en el URI que identifica el recurso que se va a recuperar.

La recuperación de un (subconjunto de) recursos de un determinado tipo se realiza imple-


mentando un GET en el URI del recurso de recolección (4.2) de ese tipo y especificando
una condición de filtro (10.2).

7.2 PUT
PUT sustituye al recurso identificado por el URI. Por lo tanto, el cuerpo del mensaje PUT
correspondiente proporciona la representación modificada pero completa de un recurso
que sustituirá completamente al recurso existente: las partes del recurso que no han cam-
biado deben incluirse en el recurso modificado del cuerpo del mensaje. Especialmente, una
solicitud PUT no debe utilizarse para una actualización parcial. Como consecuencia, PUT
es una petición idempotente (pero no segura).

Las actualizaciones parciales, es decir, las actualizaciones que modifican sólo piezas selec-
tivas de un recurso existente, deben realizarse por medio de los recursos de la función de
procesamiento correspondientes (véase la sección 7.3).

Nota: PUT se puede utilizar para crear un nuevo recurso, pero no se recomienda. La ra-
zón es que en este caso, el cliente se encarga de crear una URI única global identificando
el recurso recién creado - y garantizar la unicidad de los identificados es una tarea difícil.
Por el contrario, el uso de POST para crear nuevos recursos evita que el cliente cree
identificadores únicos porque el servidor creará el URI y lo devolverá al cliente (consulte
la sección 7.3).

www.chakray.com 15
7.3 POST
POST no es seguro ni idempotente. Los principales usos de POST son la creación de un
nuevo recurso y la iniciación de funciones, es decir, interactuar con los recursos de la fun-
ción de procesamiento (4.5), así como con los recursos del controlador (4.4).

Para crear un nuevo recurso se utiliza una petición POST con el URI del recurso de reco-
lección al que se debe agregar el nuevo recurso. Si el POST se procesa correctamente, el
mensaje de respuesta incluirá expresamente un encabezado de localización, que tendrá el
URI recién creado del recurso agregado como valor. Además, es una buena práctica devol-
ver en el mensaje de respuesta un encabezado Last-Modified que contiene la hora en que
se ha creado el recurso, así como el encabezado ETag (Entity Tag) que contiene la etiqueta
de entidad del nuevo recurso.

A menudo es apropiado que el cliente compruebe la corrección del recurso creado. Para
este propósito, el cuerpo del mensaje de respuesta contiene el recurso tal como se de-
volvería recuperándolo del URI del encabezado Location. En este caso, el mensaje de res-
puesta también incluye una encabezado de ubicación de contenido que repite el URI del
recurso recién creado.

7.4 DELETE
Un recurso se elimina mediante la solicitud DELETE en el URI del recurso. Una vez que una
solicitud DELETE se devuelve correctamente con una respuesta “200 OK”, las peticiones
DELETE siguientes en el mismo URI darán como resultado una respuesta “404 Not Found”
porque no habrá ningún recurso disponible con el URI del recurso eliminado.

Nota: Por definición, DELETE es una petición idempotente, que tiene la siguiente curiosa
implicación teórica. Responder con “200 OK” al primer DELETE y con “404 Not Found”
para cualquier DELETE adicional en el mismo URI no es RESTful porque las respuestas de
la primera y todas las demás solicitudes son diferentes, por lo tanto, la solicitud no es idem-
potente. Para cumplir plenamente con el estilo REST, un servidor tendría que mantener
todos los URI de los recursos eliminados para responder siempre con “200 OK”, es decir,
con la misma respuesta. Esto se considera mucho esfuerzo para casi ninguna ganancia, por
lo que no se aplica en la práctica.

www.chakray.com 16
8. Encabezados

Los encabezados HTTP proporcionan el vehículo para muchas propiedades no funciona-


les de las API de REST. La siguiente lista de encabezados HTTP se utiliza en la mayoría
de las API.

8.1 Encabezados de solicitudes (Request Headers)

Accept
Esta es la lista de tipos contenidos aceptables por el cliente

Authorization
Las credenciales del cliente para la autentificación por el servidor

Content-type
Este el tipo MIME de cuerpo del mensaje de las peticiones PUT o POST

If-Match
Se usa para evitar conflictos de concurrencia: si la etiqueta de entidad pasada por el
cliente es idéntica a la etiqueta de entidad del recurso en el lado del servidor, la peti-
ción se realiza.

If-Modified-Since
Se utiliza para evitar la recuperación de datos que el cliente ha almacenado en caché.
Si la marca de tiempo proporcionada por el cliente es idéntica al momento en que
la entidad ha sido modificada por última vez en el lado del servidor, no se devuelve
ningún cuerpo del mensaje.

If-None-Match
Se utiliza para evitar la recuperación de datos que el cliente ha almacenado en caché. Si
la etiqueta de entidad proporcionada por el cliente es idéntica a la etiqueta de entidad
del recurso en el lado del servidor, no se devuelve ningún cuerpo de mensaje.

If-Unmodified-Since
Se utiliza para evitar conflictos de concurrencia. Si la marca de hora modificada pasada
por el cliente es idéntica al momento en que se ha cambiado el último recurso en el
lado del servidor, se realiza la solicitud.

www.chakray.com 17
8.2 Encabezados de respuesta (Response Headers)

Content-Location
La dirección URL del cuerpo del mensaje. Por ejemplo, la URL del recurso que describe
el estado de una solicitud de ejecución larga (consulte 10.6).

Content-Type
El tipo MIME del cuerpo del mensaje.

ETag
Una “marca” del recurso como que está actualmente disponible en el servidor, a menu-
do un resumen del recurso.

Last-Modified
La marca de tiempo de cuándo ha sido modificado el recurso la última vez en el servidor.

Location
La URL de un recurso recién creado.

WWW-Authenticate
Una indicación del esquema de autenticación que se utilizará para acceder al recurso.

www.chakray.com 18
9. Códigos de estatus (Status Codes)

Los códigos de estado HTTP [9] son ​​devueltos por mensajes de respuesta y proporcionan
información clave a los clientes sobre el estado de una solicitud. Los códigos de estado
siguientes se utilizan en muchas API.

200 OK
La solicitud se ha realizado correctamente. Si la solicitud era un GET, el recurso soli-
citado se devuelve en el cuerpo del mensaje. Si la solicitud era un POST, el cuerpo del
mensaje describe el resultado de la acción solicitada o está contenido en el cuerpo
del mensaje.

201 Created
La solicitud se ha realizado correctamente. La dirección URL de la entidad recién crea-
da se encuentra en el encabezado Ubicación de la respuesta. Un encabezado ETag
debe devolverse con la etiqueta de entidad actual del recurso recién creado. La res-
puesta también puede contener una entidad correspondiente al recurso creado.

202 Accepted
El procesamiento de la solicitud ha comenzado pero tardará algún tiempo (véase 10.6).
El éxito del proceso no está garantizado y debe ser revisado por el cliente. El cuerpo
del mensaje de respuesta debe proporcionar información sobre el estado actual del
procesamiento, así como información sobre dónde puede solicitar el cliente informa-
ción de estado actualizada en un momento posterior. Normalmente, el encabezado
Content-Location de la respuesta contiene una dirección URL en la que se puede re-
cuperar esta información de estado a través de GET.

303 See Other


La respuesta de la solicitud está disponible en una dirección URL diferente. Esta direc-
ción URL se da como valor del encabezado Ubicación del mensaje de respuesta. Nor-
malmente, este código de estado se devuelve después de completar el procesamiento
de una solicitud de ejecución larga y el cliente recupera el estado de la solicitud de
ejecución larga (consulte 10.6).

304 Not Modified


El cliente solicitante ya ha recibido la última versión del recurso solicitado. Por lo tan-
to, el cuerpo del mensaje de respuesta debe estar vacío. Este código de estado se de-
vuelve como resultado de un GET condicional (véase 10.4) en el que no cumplen las
condiciones especificadas (es decir, If-Non-Match, IfModified-Since).

www.chakray.com 19
400 Bad Request
La solicitud no es válida. Por ejemplo, se encuentran errores de sintaxis en las expre-
siones pasadas con la solicitud, los valores están fuera del rango, faltan datos reque-
ridos, etc.

401 Unauthorized
La solicitud requiere autorización del cliente o las credenciales pasadas no se acep-
tan. La respuesta debe incluir un encabezado WWW-Authenticate. La solicitud pue-
de ser repetida por el cliente incluyendo credenciales apropiadas en los encabeza-
dos de Authorization.

403 Forbidden
El servidor entendió la solicitud pero se negó a realizarla. Por ejemplo, cuando la solici-
tud debe ser condicional pero no se ha especificado ninguna condición.

404 Not Found


La entidad requerida no existe.

406 Not Acceptable


El tipo de medio solicitado no es compatible. Por ejemplo, una solicitud GET desea
recuperar una entidad en un tipo de medio (especificado como valor del encabezado
Accept de la solicitud) que no es soportado por el servidor.

412 Precondition Failed


La solicitud no se ha realizado porque una de las condiciones previas no se ha cum-
plido. Este código de estado se devuelve cuando la solicitud era condicional (véase
10.5) y una de las condiciones especificadas (es decir, If-Match, IfUnmodified-Since)
no se cumple.

415 Unsupported Media Type


La entidad pasada por la solicitud estaba en un formato que no es compatible. Por
ejemplo, una petición PUT pasó una entidad en su cuerpo, y esta entidad estaba en un
formato o tipo de medio, respectivamente, que no es entendido por el servidor.

Nota: Los códigos de estado 5xx indican errores graves en el lado del servidor o en la red, o
denotan funciones no implementadas, etc. Tales errores son muy genéricos, por lo que no
hay necesidad de documentarlos explícitamente para una API.

www.chakray.com 20
10. Comportamiento especial

A excepción de APIs muy simples, una API REST tiene que ofrecer características que per-
mitan hacer frente a situaciones avanzadas como conjuntos de resultados grandes, actua-
lizaciones simultáneas o solicitudes de ejecución larga. A continuación se describen las me-
jores prácticas para hacer frente a algunas de esas situaciones especiales.

Nota: Es una buena práctica para una API soportar al menos cadenas de consultas (ver
10.2) y paginación (ver 10.3). Por ejemplo, esto permitirá soportar push-down de filtrado,
etc. desde una orquestación de API (una tecnología API cada vez más importante) a las API
individuales como optimización del tiempo de respuesta, uso de ancho de banda, etc.

10.1 Negociación de contenido


El estilo REST distingue claramente entre un recurso en sí mismo (es decir, como una en-
tidad abstracta) y sus diferentes representaciones posibles. Dicha representación es una
representación del contenido de información del recurso en el formato de un cierto tipo
de medio. Qué representación de un recurso se devuelve como el contenido del cuerpo
del mensaje se negocia entre un cliente y el proveedor del recurso (esto se conoce come
negociación del contenido).

La negociación de contenido impulsada por el servidor asume que un servidor que procesa
una solicitud determina la representación más adecuada para el cliente solicitante. El ser-
vidor depende del cliente solicitante para especificar información sobre sus capacidades
o requisitos de procesamiento. Este último se realiza por medio de encabezamiento del
mensaje de solicitud como Accept, AcceptEncoding, etc.

En la negociación de contenido orientada al cliente, el servidor detecta que tiene más de


una representación de un recurso disponible que puede satisfacer las necesidades del
cliente. El servidor responde a la petición con un mensaje “300 Multiple Choices” que lleva
información sobre las representaciones disponibles, y el cliente finalmente selecciona una
de estas representaciones y la solicita explícitamente en una petición siguiente.

La negociación de contenido dirigida por el servidor tiene la ventaja de evitar una segun-
da petición que debe realizar el cliente, pero tiene la desventaja de poder responder una
representación al cliente que no es ideal. La negociación de contenido basada en el cliente
tiene la ventaja de que el cliente obtiene la representación que mejor se adapta a ella, pero
la desventaja de dos viajes de ida y vuelta.

En la solicitud siguiente, el cliente especifica que es capaz de procesar JSON, XML, así
como texto sin formato, pero que prefiere JSON. Las preferencias en los tipos de medios
se especifican ponderando un tipo de medio por un valor de calidad Q. El servidor deter-
minará cuál de las representaciones tiene disponible y devolverá el que tenga el valor de
calidad más alto.

www.chakray.com 21
Ejemplo:

GET /products/27182
Accept: application/json;q=0.9, application/xml;q=0.6, text/plain;q=0.1

En caso de que el servidor no tenga una representación especificada por el cliente, respon-
derá con un mensaje que devuelve un código de estado correspondiente:

HTTP/1.1 406 Not aceptable

Nota: incluso en el caso de que un documento de API admita sólo un tipo de medio deter-
minado, un cliente puede pasar una solicitud que contenga un encabezado Accept con un
tipo de medio diferente. En este caso, la implementación de API debe devolver el mensaje
“406 Not acceptable”.

10.2 Consultas
Una consulta en un recurso de recolección consta de tres artefactos: (i) una condición de
filtro obligatoria, (ii) una expresión de clasificación opcional y (iii) una proyección opcional.
En primer lugar, hay que distinguir una lista de atributos del tipo de entidad que puede uti-
lizarse en cualquiera de estos artefactos en los que se basa la colección.

Una condición de filtro es una expresión booleana en estos atributos. El espectro de con-
diciones de filtro va de simple (soportando especificar un nombre de atributo único con un
valor que se compara por igualdad) a complejo (condiciones arbitrarias y operadores de
comparación arbitraria).

Ejemplo de una solicitud compleja:

filter=((price > 1000 AND status = on-stock) OR (price < 200 AND NOT(status = on-stock)))

Una expresión de ordenación consiste en una lista de nombres de atributos junto con la
indicación para cada nombre de atributo si el resultado debe ordenarse ascendente o des-
cendente con respecto al atributo correspondiente. El orden en el que se clasifica el resul-
tado está implícito en el orden de la lista de nombres de atributos.

Ejemplo:

sort=(price ASC, delivery-date DESC)

www.chakray.com 22
La lista de nombres de atributos que se han de utilizar para crear cada elemento en el con-
junto de resultados se denomina proyección. Cada nombre de atributo especificado se uti-
liza para extraer la información correspondiente de cada recurso calificado y compilar un
elemento correspondiente en el conjunto de resultados.

Ejemplo:

projection=price,color,status

Hay dos formas de habilitar las consultas en las colecciones. En primer lugar, una consulta
forma parte de la cadena de consulta del URI utilizado por un GET. En segundo lugar, la
consulta se pasa en el cuerpo de una petición POST de un recurso de función de procesa-
miento especial.

Un ejemplo de especificación de una consulta como una cadena de consultas del URI es:

GET /products?status=on-stock&sortAsc=price&projection=price,color,status HTTP/1.1

La forma preferida para hacer consultas es especificar una consulta como parte de una ca-
dena de consulta concatenada a la URI del recurso de recolección que se consulta. Esto se
debe a que con este URI se utiliza un GET, que expresa claramente la semántica de la solici-
tud, esto es, la recuperación de un subconjunto de la colección. Sin embargo, en la práctica
los URIs tienen una longitud máxima dependiendo del navegador o servidor Web utilizado.
Cuando las consultas llegan a ser tan complejas que pueden sobrepasar la longitud máxima
se aplica el uso de una petición POST que contiene la consulta (compleja) en el cuerpo de
la solicitud. Para este propósito, se debe realizar un recurso de función de procesamiento
separado:

POST /product-search HTTP/1.1

filter=((price > 1000 AND status = on-stock) OR (price < 200 AND NOT(status = on-stock))) sort=(price
ASC, delivery-date DESC) projection=price,color,status

10.3 Paginación
Cuando se va a recuperar un recurso de recopilación grande (o subconjuntos del mismo), a
menudo es conveniente recuperar el conjunto de resultados en trozos más pequeños: por
ejemplo, se reduce la latencia de la solicitud, los clientes pueden predecir la cantidad de
datos que deben tratarse, etc.

www.chakray.com 23
Para este propósito, la solicitud de recuperación especifica una cadena de consulta que
contiene un campo “desplazamiento”, así como un campo “límite”. El desplazamiento es el
número de posición del recurso calificado en el que debe iniciarse la recuperación y el lími-
te es el número máximo de recursos que se devolverá.

El mensaje de respuesta con el subconjunto del recurso calificado devuelto debe espe-
cificar el número total de todos los recursos calificados (campo “contar”), un enlace al si-
guiente fragmento de recursos calificados (campo “siguiente”), así como un enlace a los
recursos cualificados anteriores (campo “anterior”). El formato real de cómo se devuelven
estos campos, así como el conjunto de recursos, es específico de la aplicación. El siguiente
ejemplo pretende mostrar solamente el principio que rige.

Ejemplo:

GET /products?offset=42&limit=3

Respuesta:

HTTP/1.1 200 OK
count=119 next={link-to-next-subset}
previous={link-to-previous-subset}
P42-details
P43-details
P44-details

10.4 Almacenamiento cache en el lado del cliente


Un cliente puede almacenar en caché los recursos, así como los encabezados de los recur-
sos para reducir la transferencia de datos que no se han cambiado desde su última recu-
peración. Para este propósito, un cliente utiliza una solicitud condicional para recuperar
datos. Dicha solicitud condicional especifica los encabezados If-None-Match o If-Modi-
fied-Since en la solicitud.

El valor del encabezado If-None-Match es el valor del encabezado ETag del recurso recu-
perado la última vez por el cliente solicitante. El valor del encabezado If-Modified-Since es
el valor del encabezado Last-Modified del recurso recuperado la última vez por el cliente
solicitante. Al realizar la solicitud condicional, la implementación de la API tiene que com-
parar los valores pasados ​​por el cliente en la solicitud con los valores correspondientes del
recurso actual almacenados por el servidor (tenga en cuenta3 que If-None-Match tiene
prioridad sobre If-Modified-Since). Si los valores no han cambiado, el recurso no se devuel-
ve (código de respuesta “304 not modified”). De lo contrario, se devuelve el recurso.

www.chakray.com 24
Ejemplo:

GET /products/31415
If-None-Match: “42049dcaf450987cffd”
If-Modified-Since: Thu, 7 Jan 2016 17:41 CET

Respuesta:

HTTP/1.1 304 Not Modified

10.5 Control de concurrencia


Múltiples clientes que interactúan con el mismo recurso pueden causar conflictos de con-
currencia como las actualizaciones perdidas. Los mecanismos de control de concurrencia
pesimista evitan los conflictos de antemano bloqueando los recursos. Esta es una buena
opción si la probabilidad de conflictos es alta. El control de concurrencia optimista evita los
conflictos al detectar conflictos y señalarlos a los clientes que pueden volver a intentar sus
solicitudes. Esta es una buena opción si la probabilidad de conflictos es baja.

Muchas interacciones simultáneas en las API basadas en REST pueden ser manejadas por
el control de concurrencia optimista. Para este propósito, las solicitudes se envían como
solicitudes condicionales. Una solicitud condicional especifica el encabezado If-Match o
If-Unmodified-Since en la solicitud. El valor del encabezado IfMatch es el valor del enca-
bezado ETag del recurso recuperado la última vez por el cliente solicitante. El valor del
encabezado If-Unmodified-Since es el valor del encabezado LastModified del recurso re-
cuperado la última vez por el cliente solicitante. Cuando se realiza la solicitud condicional,
la implementación del API tiene que comparar los valores pasados ​​por el cliente en la so-
licitud con los valores correspondientes del recurso actual almacenados por el servidor
de origen (tenga en cuenta que If-Match tiene prioridad sobre If-Unmodified -Since). Si se
han cambiado los valores, se rechaza la solicitud (código de respuesta “412 Precondition
Failed”). De lo contrario, se ejecutará la solicitud.

Ejemplo:

PUT /products/31415
If-Match: “42049dcaf450987cffd”
If-Unmodified-Since: Thu, 7 Jan 2016 17:41 CET

Respuesta:

HTTP/1.1 412 Precondition Failed

www.chakray.com 25
Para enviar solicitudes condicionales, el cliente solicitante tiene que almacenar en caché
estos valores después de haber recuperado el recurso o tiene que recuperar estos valores
por un GET en el recurso que se realiza antes de realizar la solicitud condicional. La des-
ventaja de este último es que se tiene que hacer una segunda solicitud.

Ejemplo:

GET /products/31415
...

Respuesta:

HTTP/1.1 200 OK
ETag: “4562aae7732a56”
Last-Modified: Wed, 6 Jan 2016 11:13 CET
...

Incluso con PATCH, se debe tener especial cuidado con las actualizaciones perdidas: si se
deben soportar PATCHES simultáneos, el control de concurrencia debe implementarse
como una petición condicional.

Un patrón similar puede ser utilizado para realizar actualizaciones parciales sin utilizar los
recursos de la función de procesamiento (sección 4.5): un cliente tiene que implementar
un GET en el recurso a actualizar, aplicar las actualizaciones parciales localmente y luego
enviar un PUT condicional con el recurso completo al servidor.

10.6 Peticiones largas


Las solicitudes pueden tardar demasiado en devolver la respuesta de forma sincrónica, es
decir, tales solicitudes tienen que ser procesadas de forma asíncrona. Por ejemplo, una so-
licitud como solicitar un crédito (ver ejemplo siguiente) puede dar inicio a un flujo de tra-
bajo que involucra a seres humanos que llevará algún tiempo. En este caso, la API acepta la
solicitud y devuelve tanto el URI de un recurso de tarea como el propio recurso de tarea en
el cuerpo de respuesta. El recurso de tarea es un documento como en el ejemplo siguiente,
que contiene el estado real de la solicitud de ejecución larga. El URI del recurso de tarea
se pasa en el campo de encabezado Content-Location de la respuesta. Este URI puede ser
usado por el cliente para encuestar el estado de procesamiento de la tarea de larga ejecu-
ción más adelante.

Ejemplo:

POST /apply-for-credit HTTP/1.1


...

www.chakray.com 26
Respuesta:

HTTP/1.1 202 Accepted


Content-Type: application/xml
Content-Location: http://www.shark-credits.com/apply/tasks/1

< status >


< state > running </state>
< link rel=”self” href=”.../tasks/1”/ >
< estimatedCompletion> 2020-04-01
</status>

El mensaje de respuesta especifica mediante el código de estado “202 aceptado” que la


solicitud se acepta pero se procesará de forma asíncrona. El recurso de tarea indica que la
solicitud se está ejecutando y proporciona un tiempo de finalización estimado, entre otra
información apropiada (tenga en cuenta que no existe un formato estandarizado de un re-
curso de tarea). En las solicitudes siguientes, el cliente recuperará el recurso de tarea real
mediante el valor URI del encabezado Content-Location.

GET /apply/tasks/1 HTTP/1.1


Host: www.shark-credits.com
...

La respuesta del ejemplo se realiza satisfactoriamente (“200 OK”), lo que significa que la
recuperación del recurso de tarea ha tenido éxito. Tenga en cuenta especialmente que esto
no indica que la solicitud de ejecución larga se haya completado correctamente:

HTTP/1.1 200 OK
Content-Type: application/xml
Content-Location: http://www.shark-credits.com/apply/tasks/1

< status >


< state > running </state>
< link rel=”self” href=”.../tasks/1”/ >
< estimatedCompletion> 2020-10-10>
</status>

Después de algún tiempo, la solicitud de ejecución larga se habrá completado, es decir, la


solicitud GET anterior recibirá la siguiente respuesta:

HTTP/1.1 303 See Other


Content-Type: application/xml
Location: http://www.shark-credits.com/apply-for-credit
Content-Location: http://www.shark-credits.com/apply/tasks/1

< status >


< state > ready </state>
< link rel=”self” href=”.../tasks/1”/ >
< message> Image processed & stored
</status>

www.chakray.com 27
El código de estado “303 See Other” especifica que se ha creado un nuevo recurso con
el URI con el valor de encabezado Location. Este es el URI del resultado de la solicitud de
ejecución larga. El recurso de tarea ahora informa en su campo de estado que la solicitud
larga se ha realizado correctamente.

La solicitud de ejecución larga puede fallar. En este caso, la recuperación del recurso de
tarea tendrá éxito con un código de estado “200 OK” y el estado del recurso de tarea infor-
mará de que la solicitud de ejecución larga se completó pero no se realizó correctamente.
Por lo tanto, debe tenerse en cuenta que el código de estado de la respuesta de la recupe-
ración del recurso de tarea no está relacionado con el estado de la solicitud de ejecución
larga en absoluto.

HTTP/1.1 200 OK
Content-Type: application/xml
Content-Location: http://www.shark-credits.com/apply/tasks/1

< status >


< state > FAILED </state>
< link rel=”self” href=”.../tasks/1”/ >
< estimatedCompletion> 2020-10-10 </estimatedCompletion>
</status>

www.chakray.com 28
11. Reporte de errores
Cuando se devuelve un código de estado 4xx es que se ha detectado un error de cliente. En
este caso, se debe devolver información de error más detallada en el cuerpo del mensaje
de respuesta. La siguiente información de error (en YAML) que detalla el error del cliente
ayudará al cliente a entender cómo solucionar la solicitud y repetirla con éxito.

Error:
title: Error object returned with 4XX HTTP status code
required:
- code
- message
properties:
code:
type: integer
format: int64
description: |
A product-specific error code.
message:
type: string
description: |
A detailed description of the error occured.
description:
type: string
description: |
A short description about the error message.
moreInfo:
type: string
description: |
Preferably a URL with more details about the error.
error:
type: array
description: |
If more than one error occurred they are listed separately.
For example, list out validation errors by each field.
items:
$ref: ‘#/definitions/ErrorListItem’

Si se produjo más de un error, cada error se informa como un elemento de la siguiente


matriz que forma parte del objeto de error anterior.

ErrorListItem:
title: Description of individual errors that may have occurred during a request.
required:
- code
- message
properties:
code:
type: integer
format: int64
message:
type: string
description: |
Description about the individual error occurred

www.chakray.com 29
12. Seguridad

El acceso a los recursos de una API normalmente está asegurado. Estos recursos deben
ser accesibles basándose ​​en un modelo de permiso correctamente diseñado para evitar
el mal uso de las API. Por ejemplo, se necesita agregar, actualizar o eliminar permisos para
acceder a recursos u operaciones, así como a usuarios o roles asociados, etc. Además, los
requisitos de acceso pueden cambiar, es decir, se requiere la capacidad de administrar es-
tos permisos con flexibilidad.

Los siguientes ejemplos lo aclaran:

• El usuario que creó un carrito de compra tiene permiso para crear y eliminar un elemen-
to individual de su carrito de compra.

• Los usuarios necesitan permisos explícitos para agregar nuevos productos o actualizar
la información del producto existente.

• Un grupo diferente de usuarios obtendrá permiso para eliminar clientes (por ejemplo,
aquellos con mala reputación de crédito).

Por lo tanto, diferentes recursos están protegidos por diferentes permisos que pueden
cambiar. Para apoyar esto, las API de REST necesitan soportar mecanismos de seguridad
extensibles como autenticación básica HTTP, OAuth (Open Authentication) o XACML (eX-
tensible Access Control Markup Language).

Nota: Debido a la complejidad de XACML, OAuth es la forma más práctica de agregar segu-
ridad a las API. En lo que sigue, XACML se esboza sólo para hacer esta guía más completa.

12.1 Base de la autenticación


La autenticación HTTP básica [11] requiere que una solicitud contenga un campo de en-
cabezado de Autorización que contenga credenciales de ID de usuario y contraseña en la
codificación Base64:

Authorization: Basic Zm9d03wWUdz==

En caso de que la solicitud no contenga las credenciales, el servidor responderá con un


código de estado 401 que contiene la información sobre los recursos protegidos (“realm”)
y el nombre del esquema de autenticación que se va a utilizar (es decir, “Básico”):

HTTP/1.1 401 Unauthorized


...
WWW-Authenticate: Basic realm=”/product”
...

www.chakray.com 30
Esta información será utilizada por el cliente para producir el valor correcto del encabe-
zado de Autorización que se pasará con la solicitud repetida. De lo contrario, la solicitud
volverá a fallar.

Tenga en cuenta que la autenticación HTTP básica no es segura. Esto se debe a que las
credenciales están en texto sin cifrar, es decir, se codifica en Base64, que puede tradu-
cirse inmediatamente a texto claro. Debido a esto, la autenticación básica HTTP sólo es
viable a través de HTTPS. La codificación HTTP Digest es más segura, pero está sujeta a
un “ataque de hombre del medio”. Mediante el uso de HTTPS, esto se evita. Por lo tanto,
los mecanismos de seguridad HTTP sólo son aceptables para las API no críticas, para las
solicitudes que generan tokens de acceso más seguros (véase a continuación) se utiliza
únicamente HTTPS.

12.2 Autorización abierta (OAuth)


La probabilidad de posibles ataques de HTTP Basic o Digest Authentication se reduce
mediante el uso de tokens OAuth [12] con el mecanismo de autenticación HTTP Bearer.
El mensaje de solicitud contiene un encabezado de autenticación con el token de acceso
de OAuth:

Authorization: Bearer mF_9.B5f-4.1JqM,

La serie después de la palabra clave Bearer es la credencial proporcionada por medio de


protocolos y mecanismos OAuth. El valor del campo de alcance es una lista de series que
indican los recursos a los que debe acceder la solicitud. En caso de que el token proporcio-
nado no sea suficiente para los alcalnces, la solicitud falla.

Nota: El uso de la protección OAuth de las API requiere un diseño de alcance junto con las
API. Es necesario diseñar un conjunto de alcalnces que proteja recursos de funciones de
procesamiento individuales, (subconjuntos de) recursos de recolección o la capacidad de
crear o eliminar recursos, por ejemplo.

Aunque OAuth reduce la probabilidad de ataques cuando se usa a través de HTTP, existen
varios ataques conocidos por OAuth. Por lo tanto, aunque OAuth se ha propuesto como
un mecanismo sobre HTTP, debería ser utilizado sobre HTTPS para aumentar la seguridad.

12.3 eXtensible Access Control Markup Language (XACML)


Un control más depurado de acceso a los recursos (es decir, más refinado que los alcances)
es el soportado por XACML [13], sin embargo XACML se considera bastante complejo en
la práctica. El siguiente esbozo debería corroborarlo.

www.chakray.com 31
XACML es un mecanismo de control de acceso basado en atributos (ABAC), en contraste
con los mecanismos de control de acceso basados ​​en roles (RBAC). Como tal, el acceso a
un recurso se determina en función de los atributos contenidos en un mensaje de solicitud.
Para ello, XACML describe un lenguaje de políticas de control de acceso, un lenguaje y
protocolo de solicitud / respuesta y una arquitectura de referencia. El lenguaje de políti-
cas se utiliza para expresar políticas de control de acceso (quién puede hacer qué en qué
contexto). El lenguaje de solicitud / respuesta admite consultas sobre si se debe permitir
un acceso particular (solicitudes) y especifica respuestas a esas consultas (respuestas). La
arquitectura de referencia propone el despliegue de los componentes necesarios dentro
de una infraestructura para permitir la aplicación eficiente de las políticas.

Procesamiento XACML

Cuando se utiliza XACML para asegurar el acceso a la API, se asume el uso de un punto
de aplicación de políticas (PEP). Es el encargado de extraer los parámetros requeridos
del mensaje de solicitud de la API. Los permisos se validan mediante un punto de decisión
de política (PDP) basado en estos parámetros. El PEP creará una petición XACML basada
en los parámetros extraídos. Esta solicitud se envía al PDP para validar los permisos. El
resultado de la validación de permisos es devuelto por el PDP en el mensaje de respues-
ta basándose en directivas predefinidas. El mensaje de respuesta contendrá uno de los
siguientes estados:

Permiso - se concede el acceso.


Negar - el acceso no se concede.
Indeterminado - se produjo un error, o faltaban algunos datos requeridos y no se pudo
tomar ninguna decisión.
No aplicable - no se pudo procesar la solicitud

Implicaciones en el diseño de la API

Cuando se recibe una llamada de API, el PEP debe devolver un código de estado HTTP
401 no autorizado si algo diferente a Permitir resulta de la validación de acceso. En caso
de que la solicitud esté autorizada (es decir, Permiso resultante de la validación de acceso),
la solicitud se pasará a la implementación de la API.

XACML se puede utilizar con otros mecanismos de autenticación o autorización, como Au-
torización básica de HTTP o OAuth.

Nota: El uso de XACML para proteger API requiere (i) una implementación que siga la
arquitectura anterior, y (ii) la capacidad de los administradores de API para definir polí-
ticas correspondientes.

www.chakray.com 32
13. Referencias

1. http://martinfowler.com/articles/richardsonMaturityModel.html

2. M. Masse: REST API - Design Rulebook. O’Reilly 2012.

3. S. Allamaraju: RESTful Web Services Cookbook. O’Reilly 2010.

4. J. Webber, S. Parastatidis, I. Robinson: REST in Practice. O’Reilly 2010.

5. https://github.com/tfredrich/RestApiTutorial.com/blob/master/media/
RESTful%20Best%20Practices-v1_2.pdf

6. https://en.wikipedia.org/wiki/Software_versioning

7. https://tools.ietf.org/html/rfc5789

8. http://tools.ietf.org/html/rfc6570

9. http://www.restapitutorial.com/httpstatuscodes.html

10. http://www.danieljacobson.com/blog/306

11. https://tools.ietf.org/html/rfc2617

12. https://tools.ietf.org/html/rfc6749

13. http://docs.oasis-open.org/xacml/3.0/xacml-3.0-core-spec-cs-01-en.pdf

[1] Las secuencias entre paréntesis curvos {} representan variables que tienen que ser
sustituidas por las estructuras específicas de la API.

[2] Las secuencias entre paréntesis cuadrados [] representan elementos opcionales.

[3] http://tools.ietf.org/html/rfc7232#section-6

www.chakray.com 33
Sobre el autor: WSO2
WSO2 es la única compañía que ofrece una plataforma de aplicaciones completamente in-
tegridad con la empresa que permite a las compañías construir y conectar APIs, aplicacio-
nes, servicios web, iPaaS, PaaS y conexiones heredadas sin tener que escribir código. Solo
usando big data y mobile y fomentando la reutilización a través de una plataforma social
entre empresas. Solo con WSO2, las empresas pueden contar una familia de soluciones
seguras construidas con el mismo código base para extender su ecosistema a través de la
nube y en dispositivos móviles de los empleados, clientes y partners en la forma que deseen.
WSO2 tiene cientos de clientes que son empresas líderes en diferentes sectores - como los
sectores de salud, financiero, ventas, logística, telecom, fabricación, viajes y tecnología. En
cualquier lugar del mundo existen empresas que confían en la premiada plataforma 100%
opensource de WSO2 para sus aplicaciones críticas. Para saber más visita http://wso2.com
o echa un vistazo a la comunidad WSO2 en su blog, Twitter, LinkedIn y Facebook.

Sobre el traductor: Chakray


Chakray, WSO2 Premier Partner, es el único partner nativamente hispanohablante de
WSO2. Chakray reúne a un equipo altamente cualificado para ofrecer servicios de ar-
quitectura, consultoría y formación de Sistemas de Información Críticos. Chakray es ex-
perto en desarrollar proyectos de Open Source serios y profesionales con la tecnología
más innovadora de WSO2. ¿Su único objetivo?: Hacer que la tecnología de la empresa
sea la mejor.

www.chakray.com 34
¡Muchas gracias!

Sobre Chakray:
Hacemos bien las cosas

En Chakray somos especialistas en servicios de arquitectura, consultoría y


formación de Sistemas de Información Críticos. Nuestro equipo desarrolla
proyectos de Open Source con el software más innovador de WSO2 con un
único objetivo: Hacer que la tecnología de tu empresa sea la mejor.

¿Quieres mejorar tus sistemas?


¡Consulta a nuestros expertos!

Pregunta sin compromiso a nuestros consultores.


Te ayudaremos a encontrar la mejor solución
para tu proyecto.

CONTACTA CON NOSOTROS

www.chakray.com 35
info@chakray.com www.chakray.com

www.chakray.com 36

También podría gustarte