# Web services REST

[← Volver al índice](../crudl.md)

Las operaciones Create, Read, Update, Delete y List invocadas a través de los métodos HTTP correspondientes y **sin** el encabezado `Accept: text/html` implementan automáticamente la funcionalidad esperada de un servicio <a href="https://en.wikipedia.org/wiki/REST" target="_blank">REST</a>.

Funcionando como servicios Web, las vistas específicas no se emplean, pero sí los modelos específicos si existen.

La carga útil se envía en JSON y la respuesta la genera la vista genérica, también en JSON.

## Punto final

```
{ruta_del_sistema}/{tipo_entidad}/{identificador}
```

La forma concreta depende de sus reglas en `routes.map`. Si la conexión se indica por URL, los parámetros `_app_group` y `_connection` pueden formar parte de la ruta:

```
{ruta}/{aplicación}/{conexión}/{tipo_entidad}/{identificador}
```

Ver [Enrutamiento y enmascaramiento de URL](enrutamiento.md).

## Autenticación

El identificador de sesión se transporta habitualmente en el encabezado `Authorization`:

```
Authorization: bearer TOKEN_DE_SESION
```

También se admiten otras ubicaciones. Ver [Conexión a la base de datos y sesión](conexion-y-sesion.md#cómo-llega-el-identificador-de-sesión).

Tenga presente que si el token está ausente o es inválido, la solicitud no se rechaza necesariamente: puede atenderse con el modo de conexión constante, si el punto de entrada lo tiene configurado.

## CREATE

Crea (agrega) una nueva entidad.

**Solicitud**

* Método: `POST`
* Punto final: `.../{tipo_entidad}/`
* `Content-Type: application/json;charset=utf-8`
* Carga útil: la entidad en JSON

**Respuesta**

* `Content-Type: application/json;charset=utf-8`
* Código: `200`
* Cuerpo: la entidad completa, releída de la base de datos

La respuesta incluye los campos de sistema asignados (`sys_pk`, `sys_guid`, `sys_dtcreated`, `sys_recver`) y los elementos dependientes, si la entidad los declara.

## READ

Obtiene una entidad completa.

**Solicitud**

* Método: `GET`
* Punto final: `.../{tipo_entidad}/{identificador}/`

**Respuesta**

* `Content-Type: application/json;charset=utf-8`
* Código: `200`
* Cuerpo: la entidad completa

Si el identificador no corresponde a ningún registro, se responde `404`.

## UPDATE

Actualiza una entidad.

**Solicitud**

* Métodos: `PUT` o `PATCH`
* Punto final: `.../{tipo_entidad}/{identificador}/`
* `Content-Type: application/json;charset=utf-8`
* Carga útil: los campos a modificar

**Respuesta**

* `Content-Type: application/json;charset=utf-8`
* Código: `200`
* Cuerpo: la entidad completa actualizada

Use `PUT` si va a incluir todos los campos de la entidad; en caso contrario use `PATCH`. Si usa `PUT` y no incluye todos los campos, los omitidos podrán establecerse a nulo o a su valor predeterminado.

Si la entidad incluye `sys_recver`, **siempre deberá enviarlo en la carga útil**. Ver [Concurrencia](modelo.md#concurrencia).

Si no incluye el identificador en la URL, deberá incluir `sys_pk` o `sys_guid` en la carga útil. Si se indica en ambos lugares, se da prioridad a la URL.

## DELETE

Elimina una entidad.

**Solicitud**

* Método: `DELETE`
* Punto final: `.../{tipo_entidad}/{identificador}/`

**Respuesta**

* Código: `204`

La eliminación predeterminada es física y no alcanza a los elementos dependientes. Ver [Implementación del modelo](modelo.md#delete) y [Entidades maestro-detalle](maestro-detalle.md#baja).

## LIST

Devuelve una lista de entidades.

**Solicitud**

* Método: `GET`
* Punto final: `.../{tipo_entidad}/`

**Respuesta**

* `Content-Type: application/json;charset=utf-8`
* Código: `200`
* Cuerpo: arreglo de entidades en JSON

Los criterios de filtrado, orden y límite se resuelven en la consulta del modelo. Cualquier parámetro de la URL está disponible como parámetro enlazado de esa consulta. Ver [Filtros, orden y paginación](modelo.md#filtros-orden-y-paginación).

El marco no devuelve metadatos de paginación. Si su cliente los necesita, publíquelos desde un `@list` propio o desde un punto final aparte.

## Identificadores

Puede usar como identificador `sys_pk`, `sys_guid` o cualquier campo que defina como tal mediante el parámetro `_key`:

```
GET /misistema/cliente/CLI-0042/?_key=codigo
```

Si no se indica `_key`, se asume `sys_pk`.

## Errores

Los errores se devuelven como JSON con un solo campo:

```json
{ "message": "Elemento no encontrado" }
```

Códigos que produce el marco genérico:

| Código | Situación |
|---|---|
| `200` | Operación realizada (CREATE, READ, UPDATE, LIST) |
| `204` | Baja realizada |
| `404` | Elemento no encontrado; entidad no definida; operación no admitida; identidad no indicada |
| `500` | Vista no disponible; error de base de datos; cualquier error no clasificado |

Los errores originados en la base de datos, incluidos los conflictos de concurrencia y las violaciones de restricciones, se comunican como `500` con el texto del error en el campo `message`.

Si necesita códigos más específicos, señálelos desde su modelo con `rise_error` usando el código HTTP deseado; cualquier valor igual o mayor que `400` se emplea como estado de la respuesta.

## Deshabilitar operaciones

Para publicar una entidad de solo lectura, establezca a nulo los punteros de las operaciones que no desee admitir en su `model.dk`:

```
point @create to @null
point @update to @null
point @delete to @null
```

Las operaciones deshabilitadas responden `404` con el mensaje *Operación no admitida*.

## Carga de archivos

El marco no procesa cuerpos codificados como `multipart/form-data`. Si necesita recibir archivos, publique un punto final aparte.

## Documentos relacionados

* [El controlador](controlador.md)
* [Implementación del modelo](modelo.md)
* [Entidades maestro-detalle](maestro-detalle.md)
* [Conexión a la base de datos y sesión](conexion-y-sesion.md)
