Impresionante módulo comunitario

aplicación de mentira

marco API básico de la aplicación fibjs

Instalar

1
npm install fib-app [--save]

Prueba

1
npm test

Crear script básico

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
const http = require('http'); const util = require('util') const Session = require('fib-session') const App = require('../'); var app = new App('sqlite:test.db', { uuid: true }); app.db.use(require('./defs/person')); var session = new Session(new util.LruCache(20000), { timeout: 60 * 1000 }); var svr = new http.Server(8080, [ session.cookie_filter, { '/1.0': app } ]); svr.run();

¿Dónde personestá el módulo de definición de modelo? El contenido es el siguiente:

1 2 3 4 5 6 7
module.exports = db => { db.define('person', { name: String, sex: ["male", "female"], age: Number }); };

Esta es una definición ORM estándar y también puede utilizar otras funciones ORM, como verificación de tipos, eventos, etc.

Formato de datos API

Para solicitudes POST y PUT, el cuerpo de la solicitud debe estar en formato JSON y el tipo de contenido del encabezado HTTP debe establecerse en application/json.

1 2 3 4
curl -X PUT \ -H "Content-Type: application/json" \ -d '{"name": "tom","sex":"male","age":23}' \ http://localhost/1.0/person/57fbbdb0a2400000

Para todas las solicitudes, el formato de respuesta es un objeto JSON.

El código de estado HTTP indica si una solicitud fue exitosa o no. Un código de estado 2XX indica éxito, mientras que un código de estado 4XX indica que la solicitud falló. Cuando una solicitud falla, el cuerpo de la respuesta sigue siendo un objeto JSON, pero siempre contiene los campos de código y mensaje, que puede usar para depurar. Por ejemplo, si falla una solicitud de autenticación de permiso, se devolverá la siguiente información:

1 2 3 4
{ "code": 4030501, "message": "The operation isn’t allowed for clients due to class-level permissions." }

El código de código se divide en tres partes: los primeros tres dígitos 403 representan el tipo de error, 05 representa el número de la hoja de datos y 01 representa el código de error detallado.

Para las solicitudes GET, generalmente se devuelven datos del objeto. Dependiendo de la dirección de la solicitud GET, se puede devolver un objeto o una matriz. Por ejemplo:

1 2 3 4 5
{ "name": "tom", "sex": "male", "age": 23 }

o:

1 2 3 4 5 6 7 8 9 10 11 12
[ { "name": "tom", "sex": "male", "age": 23 }, { "name": "lily", "sex": "female", "age": 22 } ]

campos especiales

En los datos del objeto, hay cuatro campos con significados especiales que no se pueden cambiar a través de la API. Son id, updatedAt, createdAt, respectivamente createdBy.

Entre ellos id, updatedAtlos createdAtcampos individuales se crearán y modificarán automáticamente. createdByDebe especificar el tipo usted mismo.

API básica de acceso a objetos

Después de completar dicha definición de datos, tendrá directamente un conjunto de llamadas de interfaz que cumplen con la especificación de API REST:

URL método acción
/1.0/:nombre de clase CORREO Crear nuevo objeto
/1.0/:nombredeclase/:id CONSEGUIR Leer objeto
/1.0/:nombredeclase/:id PONER Modificar objeto
/1.0/:nombredeclase/:id BORRAR Eliminar objeto
/1.0/:nombre de clase CONSEGUIR Lista de objetos de consulta

Crear nuevo objeto

Para crear un nuevo objeto, se debe enviar una solicitud POST a la URL de la clase, que debe incluir el objeto en sí. Por ejemplo, para crear el objeto que se muestra arriba:

1 2 3 4
curl -X POST \ -H "Content-Type: application/json" \ -d '{"name": "tom","sex":"male","age":23}' \ http://localhost/1.0/person

Cuando la creación es exitosa, el retorno HTTP es 201 Creado y el cuerpo de la respuesta es un objeto JSON que contiene el ID del objeto y la marca de tiempo creada en el nuevo objeto:

1 2 3 4
{ "createdAt": "2017-11-25T01:39:35.931Z", "id": "57fbbdb0a2400000" }

Leer objeto

Cuando crea un objeto, puede recuperar su contenido enviando una solicitud GET a la Ubicación en el encabezado devuelto. Por ejemplo, para obtener el objeto que creamos arriba:

1
curl -X GET http://localhost/1.0/person/57fbbdb0a2400000

El cuerpo devuelto es un objeto JSON que contiene todos los campos proporcionados por el usuario más los campos createdAty :updatedAtid

1 2 3 4 5 6 7 8
{ "name": "tom", "sex": "male", "age": 23, "createdAt": "2017-11-25T01:39:35.931Z", "updatedAt": "2017-11-25T01:39:35.931Z", "id": "57fbbdb0a2400000" }

Al configurar el campo de devolución keys, puede personalizar el contenido devuelto, keysque es una ,cadena de nombres de campos separados por:

1
curl -X GET http://localhost/1.0/person/57fbbdb0a2400000?keys=name%2Csex

volverá:

1 2 3 4
{ "name": "tom", "sex": "male" }

Modificar objeto

Para cambiar los datos existentes de un objeto, puede enviar una solicitud PUT a la URL correspondiente del objeto. Cualquier clave que no especifique no se cambiará, por lo que solo puede actualizar un subconjunto de los datos del objeto. Por ejemplo, cambiemos un campo de edad de nuestro objeto:

1 2 3 4
curl -X PUT \ -H "Content-Type: application/json" \ -d '{"age": 25}' \ http://localhost/1.0/person/57fbbdb0a2400000

El objeto JSON devuelto contendrá updatedAtcampos idque indiquen cuándo ocurrió la actualización:

1 2 3 4
{ "updatedAt": "2017-11-25T01:39:35.931Z", "id": "57fbbdb0a2400000" }

Eliminar objeto

Para eliminar un objeto, puede enviar una solicitud DELETE a la URL del objeto especificado, por ejemplo:

1
curl -X DELETE http://localhost/1.0/person/57fbbdb0a2400000

Lista de objetos de consulta

Puede obtener varios objetos a la vez enviando una solicitud GET a la URL de la clase, sin ningún parámetro de URL. Aquí se explica cómo obtener simplemente todos los usuarios:

1
curl -X GET http://localhost/1.0/person

El valor devuelto es un objeto JSON que contiene el campo de resultados, cuyo valor es una lista de objetos:

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
[ { "name": "tom", "sex": "male", "age": 23, "createdAt": "2017-11-25T01:39:35.931Z", "updatedAt": "2017-11-25T01:39:35.931Z", "id": "57fbbdb0a2400000" }, { "name": "lily", "sex": "female", "age": 22, "createdAt": "2017-11-25T01:39:35.931Z", "updatedAt": "2017-11-25T01:39:35.931Z", "id": "57fbbdb0a2400001" } ]

personalización del campo de claves

Al igual que la consulta de objetos, puede keyspersonalizar los campos incluidos en los resultados devueltos configurándolos al consultar la lista. keysEl contenido es una ,cadena de nombres de campos separados por, por ejemplo:

1
curl -X GET http://localhost/1.0/person?keys=name%2Cage

Especificará que solo se devolverán los campos namey .age

donde condición del filtro

whereEl objeto de consulta se puede restringir en forma de parámetros.

whereEl valor del parámetro debe estar codificado en JSON. Es decir, si observa la solicitud de URL real que se realiza, primero debe codificarse en JSON y luego en URL. La whereforma más sencilla de utilizar parámetros es incluir la clave y el valor adecuados. Por ejemplo, si quisiéramos buscar usuarios llamados tom, construiríamos la consulta así:

1
curl -X GET http://localhost/1.0/person?where=%7B%22name%22%3A%22tom%22%7D

whereEl valor es una cadena JSON codificada en URL, el contenido es:{"name":"tom"}

Además de hacer coincidir exactamente un valor determinado, wheretambién se admiten métodos de comparación como la inclusión. whereLos parámetros admiten las siguientes opciones:

llave operación muestra
ecuación igual {"nombre":{"eq":"tom"}} o {"nombre":"tom"}
nordeste no igual a {"nombre":{"ne":"tom"}}
gt más que el {"edad":{"gt":"24"}}
gte mayor o igual a {"edad":{"gte":"24"}}
es menos que {"edad":{"lt":"24"}}
lte Menos que o igual a {"edad":{"lte":"24"}}
como consulta difusa {"nombre":{"me gusta":"%m"}}
diferente a consulta difusa {"nombre":{"not_like":"%m"}}
entre Comparación de intervalos {"edad":{"entre":[22,25]}}
no entre Comparación de intervalos {"edad":{"not_between":[22,25]}}
en enumerar {"nombre":{"en":["tom","lily"]}}
no en enumerar {"nombre":{"not_in":["tom","lily"]}}
o O operación {"o":[{"nombre":"tom"},{"edad":24}]}

saltar saltar registros

A través skipde la opción, puede omitir la cantidad especificada de registros para lograr el efecto de pasar página.

1
curl -X GET http://localhost/1.0/person?skip=100

límite de retornos límite de registro

A través limitde la opción, puede limitar la cantidad de registros devueltos. limitLos números válidos son del 1 al 1000 y el valor predeterminado es 100.

1
curl -X GET http://localhost/1.0/person?limit=100

orden especifica el método de clasificación

Utilice orderla opción para establecer el método de clasificación del conjunto de resultados devuelto. Cuando el nombre del campo lo contiene antes, -está en orden inverso.

1
curl -X GET http://localhost/1.0/person?order=-id

count devuelve el número total de resultados

Incrementado a petición countEl número total de conjuntos de resultados que se pueden devolver al devolver el contenido especificado.

1
curl -X GET http://localhost/1.0/person?count=1&limit=1

En este momento, el resultado devuelto contendrá dos campos: county results, que contienen el número total y el resultado respectivamente:

1 2 3 4 5 6 7 8 9 10 11 12 13
{ "count": 2, "results": [ { "name": "tom", "sex": "male", "age": 23, "createdAt": "2017-11-25T01:39:35.931Z", "updatedAt": "2017-11-25T01:39:35.931Z", "id": "57fbbdb0a2400000" } ] }

Crear objeto de extensión

Al definir hasOne y hasMany a través de ORM, puedes definir la asociación entre objetos y reflejarla en la API, por ejemplo:

1 2 3 4 5 6 7 8 9
module.exports = db => { var Person = db.models.person; var Pet = db.define('pet', { name: String }); Person.hasMany('pets', Pet); };

API de acceso extendido a objetos

La siguiente es la definición API del objeto de extensión:

URL método acción
/1.0/:nombredeclase/:id/:nombreextendido PONER Establecer objeto de extensión
/1.0/:nombredeclase/:id/:nombreextendido CORREO Crear objeto de extensión
/1.0/:nombredeclase/:id/:nombreextendido/:rid CONSEGUIR Leer objeto de extensión
/1.0/:nombredeclase/:id/:nombreextendido/:rid PONER Modificar objeto de extensión
/1.0/:nombredeclase/:id/:nombreextendido/:rid BORRAR Eliminar objeto extendido
/1.0/:nombredeclase/:id/:nombreextendido CONSEGUIR Consultar lista de objetos extendida

Establecer objeto de extensión

Establecer un objeto de extensión es establecer una relación entre dos objetos independientes. Por ejemplo, si Tom adopta una mascota llamada gato, puede utilizar las siguientes operaciones para lograrlo:

1 2 3 4
curl -X PUT \ -H "Content-Type: application/json" \ -d '{"id": "57fbbdb0a2400007"}' \ http://localhost/1.0/person/57fbbdb0a2400000/pets

En la llamada, la identificación del gato debe especificarse en el cuerpo.

Crear objeto de extensión

La creación directa de objetos extendidos puede establecer conexiones entre objetos mientras se crean objetos. Por ejemplo:

1 2 3 4
curl -X POST \ -H "Content-Type: application/json" \ -d '{"name": "cat"}' \ http://localhost/1.0/person/57fbbdb0a2400000/pets

Se creará una mascota llamada gato y se asociará con Tom.

Leer objeto de extensión

Leer objetos extendidos es muy similar a leer objetos base y también admite la opción de claves:

1
curl -X GET http://localhost/1.0/person/57fbbdb0a2400000/pets/57fbbdb0a2400007

Modificar objeto de extensión

Leer objetos extendidos es muy similar a leer objetos base:

1 2 3 4
curl -X PUT \ -H "Content-Type: application/json" \ -d '{"name": "cat 1"}' \ http://localhost/1.0/person/57fbbdb0a2400000/pets/57fbbdb0a2400007

Eliminar objeto extendido

Eliminar un objeto extendido no elimina el objeto en sí, solo disuelve la relación entre los objetos:

1
curl -X DETELE http://localhost/1.0/person/57fbbdb0a2400000/pets/57fbbdb0a2400007

Consultar lista de objetos extendida

Consultar la lista de objetos extendida es muy similar a consultar la lista de objetos básica y también admite opciones como claves y filtrado condicional:

1
curl -X GET http://localhost/1.0/person/57fbbdb0a2400000/pets

LCA

Los permisos de datos se pueden controlar definiendo la ACL del modelo. Por ejemplo:

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
const orm = require('fib-orm'); module.exports = db => { db.define('blog', { title: String, detail: Stringnote: String }, { ACL: function(session) { return { "*": { "*": false }, "57fbbdb0a2400000": { "*": true }, "roles": { "user": { "read": true } } }; } }); };

Si no se especifica ninguna ACL al definir el modelo, equivale a configurar los permisos predeterminados:

1 2 3 4 5
{ "*": { "*": true } }

cuerpo principal

Hay tres tipos de descripciones de asunto de ACL: usuario id, usuario roley *, idque representan a un usuario específico, rolerepresentan a usuarios con una determinada función y *representan a todos los usuarios:

cuerpo principal describir prioridad
IDENTIFICACIÓN identificación de usuario específica 1
role Nombre del grupo de usuarios 2
* Todo 3

Al verificar los permisos, primero coincidirá con idlos permisos correspondientes. Si no se especifica, luego coincidirá con rolelos permisos correspondientes del usuario. Si aún está especificado, verifique si *los permisos de están especificados. Si *no se especifica, no hay permiso.

Por ejemplo, en la configuración de permisos anterior, userse especifica que el grupo de usuarios puede leer. El usuario 57fbbdb0a2400000tiene todos los permisos, pero otros usuarios no tienen ningún permiso.

Permisos

ACL clasifica los permisos en cinco categorías según el comportamiento de la API:

Permisos describir tipos permitidos
crear Crear objeto verdadero/falso/matriz
leer Leer objeto verdadero/falso/matriz
escribir Modificar objeto verdadero/falso/matriz
borrar Eliminar objeto verdadero Falso
encontrar Lista de objetos de consulta verdadero Falso
* Coincidir con todos los permisos verdadero/falso/matriz

Los permisos se configuran truepara permitir el acceso, falsedenegar el acceso y arraysolo permitir el acceso a campos específicos. deletey findno se aceptan y se tratan de la misma manera arraysi se establecen . Si el permiso especificado no existe, se compararán los permisos del mismo tema. Si ninguno existe, consulte nuevamente el tema del siguiente nivel de prioridad.arraytrue*

Por ejemplo, en el ejemplo anterior, si necesita configurar usersolo lectura titley detailpermitir que otros lean title, puede configurarlo así:

1 2 3 4 5 6 7 8 9 10 11 12 13 14
{ "*": { "*": false, "read": ['title'] }, "57fbbdb0a2400000": { "*": true }, "roles": { "user": { "read": ['title', 'detail'] } } }

Permisos de objetos

Los permisos establecidos en el Modelo son los permisos de toda la clase. Si necesita establecer permisos en objetos específicos, puede hacerlo configurando OACL:

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
module.exports = db => { db.define('person', { name: String, sex: ["male", "female"], age: Number }, { ACL: function(session) { return { "*": { "*": false } } }, OACL: function(session) { var _acl = {}; if(this.id === session.id) _acl[session.id] = { "*": true }; return _acl; } }); };

En este ejemplo, cuando el visitante es el propio objeto, se permitirán todas las operaciones; de lo contrario, se prohibirá todo acceso. Los permisos se verifican de la siguiente manera:

  • person[57fbbdb0a2400000]=>OACL
  • person=>ACL

Permisos de objetos extendidos

El control de permisos de acceso de los objetos extendidos es similar a los permisos de los objetos básicos, la única diferencia es que la ACL debe especificarse por separado:

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41
module.exports = db => { var Person = db.define('person', { name: String, sex: ["male", "female"], age: Number },{ ACL: function(session) { return { "*": { "read": ['name', 'sex'], "extends": { "pets": { "read": true, "find": true } } } } }, OACL: function(session) { var _acl = {}; if(this.id === session.id) _acl[session.id] = { "*": true, "extends": { "pets": { "*": true } } }; return _acl; } }); var Pet = db.define('pet', { name: String }); Person.hasMany('pets', Pet); };

En esta definición, cualquiera puede verificar la namesuma de información personal sexy verificarla y buscarla libremente pets. El propio usuario puede operar todos sus propios datos y tener permisos completos para la información de su propia mascota.

Al verificar los permisos de acceso para objetos extendidos, los permisos de objetos y los permisos de objetos extendidos se verifican por separado. Por ejemplo, la siguiente solicitud:

1
curl -X GET http://localhost/1.0/person/57fbbdb0a2400000/pets/57fbbdb0a2400007

Los permisos se verifican de la siguiente manera:

  • pets[57fbbdb0a2400007]=>OACL
  • person[57fbbdb0a2400000]=> OACL=> extends=>pets
  • person=> ACL=> extends=>pets
  • pets=>ACL

Función

Se pueden definir API para el modelo y se pueden completar operaciones de datos complejas a través de funciones personalizadas.

La mayoría de los permisos se pueden controlar a través de ACL y no es necesario implementar los permisos basados ​​​​en objetos a través de Función. La función se puede utilizar para completar permisos basados ​​en datos, como otorgar permisos a diferentes grupos de usuarios según el estado de aprobación. Y múltiples modificaciones, como la necesidad de modificar múltiples registros de bases de datos.

Dibujar modelo de datos

Después de completar la definición de datos, puede utilizar para app.diagram()dibujar el diagrama de clases de formato del modelo de datos svg. Al guardar en un archivo, obtendrá una imagen similar a la siguiente: diagrama