<commit_before># JAQL - JSON API Query Language

### About this Version

- **Current version: 0.1-draft**
- **Previous version: [Wiki](https://github.com/pillarsjs/modelator/wiki/JAQL-Specification-(v0.1))**
- **[Open Discussions](https://github.com/pillarsjs/modelator/labels/specification)**

## Definición

**JAQL - JSON API Query Language**

JAQL define un lenguaje de consulta agnóstico en cuanto a BDD (SQL-NOSQL) que permita realizar la variedad de operaciones que ofrece Modelator desde un API restfull.

**Pillars Modelator (aka Modelator)**

Modelator permite definir esquemas de datos relacionales y la lógica de los mismos, mientras automatiza gran cantidad de tareas de desarrollo.

## Básicos

### Definición general

Modelator es una clase con (entre otros) cinco métodos que se montan sobre los correspondientes métodos HTTP, el input y output de los métodos de Modelator funcionan con JAQL por lo que el API producida funciona de la misma forma. Un API público de Modelator, uno expuesto vía HTTP, es básicamente una interface para realizar llamadas a métodos de la clase Modelator.

Modelator puede generar un API en base a un modelado (instancia de Modelator) de forma totalmente automática, gestionar su seguridad, acceso, internacionalización, relaciones, proyecciones/includes y amplio rango de acciones muy superior al básico que ofrece un API restfull al uso.

Una de las grandes diferencias de JAQL es que se trata de un lenguaje de consulta montado sobre métodos HTTP, no es una versión de RESTfull. La otra gran diferencia es que Modelator asume que el modelo es una entidad superior a la lógica, es decir, en Modelator la lógica no accede al modelo sino que el modelo gestiona la lógica.

Modelator acepta 4 métodos a ejecutar sobre un modelado:
 - myModel.insert()
 - get()
 - update()
 - remove()

Cada uno de los métodos están relacioandos con un método HTTP. A su vez cada método permite realizar operaciones especialmente complejas (transacciones relacionales, proyecciones...) descritas de forma breve y clara en utilizando JSON.


### Funcionamiento de una API basada en JAQL

Como ya hemos visto el método HTTP define el método de Modelator, pero necesitamos conocer que modelado de todos los instanciados queremos operar, para esto utilizamos el path/endpoint que sirve exclusivamente para seleccionar un modelado sobre el que realizar una operación. No existen, como ocurre en RESTfull, números indicando indices para operaciones, o sub-rutas, ya que esto es responsabilidad de las sentencias JAQL que oportan en este punto mucha más libertad para realizar operaciones que un escueto indice numérico.

> La selección del modelado (instancia de Modelator) desde JAQL se especifica por medio del PATH de la solicitud HTTP

Finalmente la sentencia que se pasa a dicho método del modelado seleccionado se define por medio del PAYLOAD de la solicitud en JSON, lo que llamamos sentencia JAQL.

> Nota: ¿porque llamamos modelado a algo que podríamos llamar colección o tabla? Porque un modelado no está asociado con una sola colección/table, un modelado es la descripción de una entidad relacional completa, es decir, todas las colecciones/tablas y sus relaciones que forman un modelo relacional. Lo que le da la facultad a Modelator de poder inferir gran cantidad de comportamientos sobre los datos por si mismo, Modelator conoce por completo el esquema relacional y por lo tanto puede hacer muchas tareas de la lógica de negocio por si mismo.

Como JAQL es un lenguaje de consulta relacional podemos comparar una consulta SQL con JAQL y comprobar como el endpoint junto con el payload en JAQL forman una consulta clásica extrapolable a SQL (y NOSQL):

**Ejemplo de consulta de datos, SIN modificación**

- SQL:
```sql
SQL: SELECT c1, c2, c3 FROM users WHERE c1 = 0;
```
- JAQL:
```txt
GET "/api/v1/users" > {select:["c1","c2","c3"], query: {c1 : 0}}
```
- Interpretación:
```txt
(HTTP METHOD: GET) (JAQL: select) (HTTP PATH: "/api/v1/users") (JAQL: query)
```

**Ejemplo de consulta de datos, CON modificación**

- SQL:
```sql
UPDATE users SET c1 = 1, c2 = 2 WHERE _id = 10
```

- JAQL:
```txt
(HTTP METHOD: PATCH) (HTTP PATH: "/api/v1/users") (JAQL: update)
```

- Interpretación:
```txt
JAQL: PATCH "/api/v1/users" > {update: {_id : 10, c1 : 1, c2: 2}}
```


## JAQL en detalle

### Básico
Una sentencia JAQL (JSON enviado en el payload de la solicitud HTTP) tiene 5 propiedades posibles y excluyentes:

 - select y query, para las llamadas al método http GET
 - insert, método INSERT
 - update, método PATCH
 - remove, método REMOVE

 > El uso de nombres de propiedad distintos permite distinguir y chequear claramente una sentencia JAQL sin necesidad de indicar por separado el método HTTP que se va a utilizar o la URL.

### Método GET, sentencias de consulta

La sentencia JAQL para el método GET consiste en un objeto JSON con las propiedades ``query`` y ``select``.

**Select**

Permite filtrar los campos que deseamos obtener ahorrando peso y tiempo de consulta, es opcional.

```json
{
  "select": ["colors","!_id"]
}
```

**Query**

Permite realizar operaciones de comparación por cada campo (>=,==,<=,!=), Modelator solo permitirá realizar operaciones de este tipo en campos indexados.

La lógica sería `(c1 > 5 AND c1 <= 10) OR c1 = 15`

```json
{
  "query": {
    "c1" : [{">": 5, "<=" : 10}, {"=" : 15}]
  }
}
```

### Método INSERT, sentencias de inserción

Las sentencias de inserción consisten en un objeto JSON con la propiedad `insert` que a su vez contendrá un objeto que representá a la nueva entidad a insertar.

```json
{
  "insert" : [{
    "c1" : 10,
    "c2" : 12
  }]
}
```


### Método PATCH, sentencias de actualización

Las sentencias de actualización consisten en un objeto JSON con la propiedad `update` donde se debe definir un objeto con la propiedad `_id` identificando a la entidad y al menos alguna otra propiedad/atributo que se desea modificar en dicha entidad.
Es posible realizar actualizaciones complejas en relaciones de cualquier profundidad.


```json
{
  "update" : {
    "_id" : "someId",
    "c1" : 10,
    "c2" : 12
  }
}
```

El campo es de tipo `list` y puede (en el meotodo PATCH) realizar operaciones de inserción, actualización o borrado de sus elementos a la vez que realizamos modificaciones en otros campos de la entidad, o en cualquier otras relacion.

Las reglas son las siguientes:
- Se actualiza un elemento si tiene `\_id` y otras propiedades (payload)
- Se borra un elemento si tiene `\_id` y carece propiedades (payload)
- Se añade un elemento nuevo si tiene propiedades (payload) pero carece de `\_id`

```json
{
  "update" : {
    "_id" : "someId",
    "c1" : 10,
    "c2" : 12,
    "list" : [  
      {
        "_id" : "n1001",
        "img": "/to.mod.file",
      },
      {
        "img" : "/to.new.file",
        "text" : "newText"
      },<commit_msg>sustituido uso de PATH por URL otros detalles menores<commit_after># JAQL - JSON API Query Language

### About this Version

- **Current version: 0.1-draft**
- **[Wiki](https://github.com/pillarsjs/modelator/wiki/JAQL-Specification-(v0.1))**
- **[Open Discussions](https://github.com/pillarsjs/modelator/labels/specification)**

## Definición

**JAQL - JSON API Query Language**

JAQL define un lenguaje de consulta agnóstico en cuanto a BDD (SQL-NOSQL) que permita realizar la variedad de operaciones que ofrece Modelator desde un API restfull.

**Pillars Modelator (aka Modelator)**

Modelator permite definir esquemas de datos relacionales y la lógica de los mismos, mientras automatiza gran cantidad de tareas de desarrollo.

## Básicos

### Definición general

Modelator es una clase con (entre otros) cinco métodos que se montan sobre los correspondientes métodos HTTP, el input y output de los métodos de Modelator funcionan con JAQL por lo que el API producida funciona de la misma forma. Un API público de Modelator, uno expuesto vía HTTP, es básicamente una interface para realizar llamadas a métodos de la clase Modelator.

Modelator puede generar un API en base a un modelado (instancia de Modelator) de forma totalmente automática, gestionar su seguridad, acceso, internacionalización, relaciones, proyecciones/includes y amplio rango de acciones muy superior al básico que ofrece un API restfull al uso.

Una de las grandes diferencias de JAQL es que se trata de un lenguaje de consulta montado sobre métodos HTTP, no es una versión de RESTfull. La otra gran diferencia es que Modelator asume que el modelo es una entidad superior a la lógica, es decir, en Modelator la lógica no accede al modelo sino que el modelo gestiona la lógica.

Modelator acepta 4 métodos a ejecutar sobre un modelado:
 - myModel.insert()
 - get()
 - update()
 - remove()

Cada uno de los métodos están relacioandos con un método HTTP. A su vez cada método permite realizar operaciones especialmente complejas (transacciones relacionales, proyecciones...) descritas de forma breve y clara utilizando JSON.


### Funcionamiento de una API basada en JAQL

Como ya hemos visto el método HTTP define el método de Modelator, pero necesitamos conocer que modelado de todos los instanciados queremos operar, para esto utilizamos el URL del endpoint que sirve exclusivamente para seleccionar un modelado sobre el que realizar una operación. No existen, como ocurre en RESTfull, números indicando indices para operaciones, o sub-rutas, ya que esto es responsabilidad de las sentencias JAQL que oportan en este punto mucha más libertad para realizar operaciones que un escueto indice numérico.

> La selección del modelado (instancia de Modelator) desde JAQL se especifica por medio de la URL de la solicitud HTTP

Finalmente la sentencia que se pasa a dicho método del modelado seleccionado se define por medio del PAYLOAD de la solicitud en JSON, lo que llamamos sentencia JAQL.

> Nota: ¿porque llamamos modelado a algo que podríamos llamar colección o tabla? Porque un modelado no está asociado con una sola colección/table, un modelado es la descripción de una entidad relacional completa, es decir, todas las colecciones/tablas y sus relaciones que forman un modelo relacional. Lo que le da la facultad a Modelator de poder inferir gran cantidad de comportamientos sobre los datos por si mismo, Modelator conoce por completo el esquema relacional y por lo tanto puede hacer muchas tareas de la lógica de negocio por si mismo.

Como JAQL es un lenguaje de consulta relacional podemos comparar una consulta SQL con JAQL y comprobar como el endpoint junto con el payload en JAQL forman una consulta clásica extrapolable a SQL (y NOSQL):

**Ejemplo de consulta de datos, SIN modificación**

- SQL:
```sql
SQL: SELECT c1, c2, c3 FROM users WHERE c1 = 0;
```
- JAQL:
```txt
GET "/api/v1/users" > {select:["c1","c2","c3"], query: {c1 : 0}}
```
- Interpretación como SQL:
```txt
(HTTP METHOD: GET) (JAQL: select) (HTTP URL: "/api/v1/users") (JAQL: query)
```

**Ejemplo de consulta de datos, CON modificación**

- SQL:
```sql
UPDATE users SET c1 = 1, c2 = 2 WHERE _id = 10
```

- JAQL:
```txt
(HTTP METHOD: PATCH) (HTTP URL: "/api/v1/users") (JAQL: update)
```

- Interpretación como SQL:
```txt
JAQL: PATCH "/api/v1/users" > {update: {_id : 10, c1 : 1, c2: 2}}
```


## JAQL en detalle

### Básico
Una sentencia JAQL (JSON enviado en el payload de la solicitud HTTP) tiene 5 propiedades posibles y excluyentes:

 - select y query, para las llamadas al método http GET
 - insert, método INSERT
 - update, método PATCH
 - remove, método REMOVE

 > El uso de nombres de propiedad distintos permite distinguir y chequear claramente una sentencia JAQL sin necesidad de indicar por separado el método HTTP que se va a utilizar o la URL.

### Método GET, sentencias de consulta

La sentencia JAQL para el método GET consiste en un objeto JSON con las propiedades ``query`` y ``select``.

**Select**

Permite filtrar los campos que deseamos obtener ahorrando peso y tiempo de consulta, es opcional.

```json
{
  "select": ["colors","!_id"]
}
```

**Query**

Permite realizar operaciones de comparación por cada campo (>=,==,<=,!=), Modelator solo permitirá realizar operaciones de este tipo en campos indexados.

La lógica sería `(c1 > 5 AND c1 <= 10) OR c1 = 15`

```json
{
  "query": {
    "c1" : [{">": 5, "<=" : 10}, {"=" : 15}]
  }
}
```

### Método INSERT, sentencias de inserción

Las sentencias de inserción consisten en un objeto JSON con la propiedad `insert` que a su vez contendrá un objeto que representá a la nueva entidad a insertar.

```json
{
  "insert" : [{
    "c1" : 10,
    "c2" : 12
  }]
}
```


### Método PATCH, sentencias de actualización

Las sentencias de actualización consisten en un objeto JSON con la propiedad `update` donde se debe definir un objeto con la propiedad `_id` identificando a la entidad y al menos alguna otra propiedad/atributo que se desea modificar en dicha entidad.
Es posible realizar actualizaciones complejas en relaciones de cualquier profundidad.


```json
{
  "update" : {
    "_id" : "someId",
    "c1" : 10,
    "c2" : 12
  }
}
```

En el siguiente ejemplo aparece una operación de actualización multiples sobre entidades anidadas. El campo `list` es de tipo `List` lo que implica que se tratá de un array de sub-entidades. Pueden realizararse operaciones de inserción, actualización o borrado de sus elementos a la vez que realizamos modificaciones en otros campos de la entidad principal.

Las reglas son las siguientes:
- Se actualiza un elemento si tiene `\_id` y otras propiedades (payload)
- Se borra un elemento si tiene `\_id` y carece propiedades (payload)
- Se añade un elemento nuevo si tiene propiedades (payload) pero carece de `\_id`

```json
{
  "update" : {
    "_id" : "someId",
    "c1" : 10,
    "c2" : 12,
    "list" : [  
      {
        "_id" : "n1001",
        "img": "/to.mod.file",
      },
      {
        "img" : "/to.new.file",
        "text" : "newText"
      },
{'fraction_non_alphanumeric': 0.08187387387387388, 'fraction_numerical': 0.009801801801801803, 'mean_word_length': 4.110865561694291, 'pattern_counts': {'":': 8, '<': 9, '<?xml version=': 0, '>': 19, 'https://': 4, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1744479', 'n_tokens_mistral': 4663, 'n_tokens_neox': 4485, 'n_words': 1974}