Módulo de comunidad impresionante

fib-app

marco de api básico de la aplicación fibjs

Instalar en pc

1
npm install fib-app [--save]

Prueba

1
npm test

Construye un guión 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();

En el que se personencuentra el módulo de definición del modelo, de la siguiente manera:

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 estándar de orm, y también se pueden usar otras funciones de orm, como verificación de tipos, eventos, etc.

Formato de datos API

Para las 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 éxito de una solicitud se indica mediante el código de estado HTTP. Un código de estado 2XX indica éxito y un 4XX indica falla en la solicitud. Cuando falla una solicitud, el cuerpo de la respuesta sigue siendo un objeto JSON, pero siempre contendrá los dos 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 se divide en tres partes: los primeros tres dígitos 403 indican el tipo de error, 05 indican el número de la tabla de datos y 01 indican el código de error detallado.

Para una solicitud GET, los datos del objeto generalmente se devuelven. 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 } ]

Campo especial

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

Donde id, updatedAt, createdAtcampos individuales se pueden crear y modificar de forma automática. createdByDebe especificar el tipo usted mismo.

API de acceso a objetos básica

Después de completar esta definición de datos, tendrá directamente un conjunto completo de llamadas de interfaz que se ajustan a la especificación de la API REST:

url método acción
/1.0/:className CORREO Crear nuevo objeto
/1.0/:className/:id OBTENER Leer objeto
/1.0/:className/:id PONER Modificar el objeto
/1.0/:className/:id ELIMINAR Eliminar objeto
/1.0/:className OBTENER 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 contener el objeto en sí. Por ejemplo, para crear el objeto como se mencionó anteriormente:

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, la respuesta HTTP es 201 Created y el cuerpo de la respuesta es un objeto JSON, incluido el objectId y la marca de tiempo createdAt del nuevo objeto:

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

Leer objeto

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

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

El cuerpo devuelve un objeto JSON contiene todas las juntas con el campo suministrados por el usuario createdAt, updatedAty idcampos:

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" }

Devuelve el campo proporcionando keyscontenido personalizado que se puede devolver keyscontenido en ,cadenas de nombres de campo divididas:

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

Regresará:

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

Modificar el objeto

Para cambiar los datos existentes de un objeto, puede enviar una solicitud PUT a la URL correspondiente del objeto. Cualquier clave que no haya especificado 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

JSON devuelto objeto contendrá updatedAty idcampo que indica la actualización se produjo en un momento:

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, como por ejemplo:

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

Lista de objetos de consulta

Al enviar una solicitud GET a la URL de la clase, puede obtener varios objetos a la vez sin ningún parámetro de URL. Lo siguiente es simplemente para obtener 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 y su 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 con la consulta de objetos, puede establecer que el keyscampo personalizado de la lista de consultas devuelva el resultado a contener. keysEl contenido está ,dividido en una cadena de nombre de campo, por ejemplo:

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

La devolución especificada solo namey agedos campos.

donde condición de filtro

Por wherepuede establecer restricciones en el objeto de consulta como parámetro.

whereEl valor del parámetro debe estar codificado en JSON. En otras palabras, si observa la solicitud de URL que realmente se envió, primero debe estar codificada en JSON y luego en la URL. Lo más fácil de usar wherecomo argumentos es incluir la clave y el valor adecuados. Por ejemplo, si queremos buscar usuarios cuyo nombre sea tom, deberíamos construir la consulta así:

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

where El valor es una cadena JSON después de urlencode, el contenido es:{"name":"tom"}

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

llave operación muestra
eq igual {"name": {"eq": "tom"}} o {"name": "tom"}
nordeste no igual a {"nombre": {"ne": "tom"}}
gt mas que el {"age": {"gt": "24"}}
gte mayor o igual a {"age": {"gte": "24"}}
es Menos que {"age": {"lt": "24"}}
lte Menos que o igual a {"age": {"lte": "24"}}
igual que Consulta difusa {"nombre": {"me gusta": "% m"}}
diferente a Consulta difusa {"nombre": {"not_like": "% m"}}
Entre Comparación de intervalo {"edad": {"entre": [22,25]}}
no entre Comparación de intervalo {"edad": {"not_between": [22,25]}}
en enumerar {"name": {"in": ["tom", "lily"]}}
no en enumerar {"nombre": {"not_in": ["tom", "lily"]}}
o O operación {"o": [{"nombre": "tom"}, {"edad": 24}]}

omitir omitir registros

De forma skipopcional, puede especificar el número de registros que se deben omitir para lograr el efecto de volteo.

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

límite devuelve el límite de registro

De forma limitopcional, puede limitar el número de registros devueltos, limitlos dígitos significativos de 1 a 1000 y los valores predeterminados a 100.

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

orden especifica el método de clasificación

Por orderconjunto de opciones para devolver Ordenar conjunto de resultados, antes de que el nombre del campo contenga -como tiempo inverso.

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

count devuelve el número total de resultados

Cuando se solicita aumentar countel número total, puede devolver un conjunto de resultados del contenido especificado al mismo tiempo.

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

En este momento, los resultados de retorno que contienen county resultsque comprende dos campos, y cada uno un número total de resultados:

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" } ] }

Crea un objeto de extensión

Al definir hasOne y hasMany a través de orm, la relación de asociación entre objetos se puede definir y reflejar 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 a objetos extendido

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

url método acción
/1.0/:className/:id/:extendName PONER Establecer objeto de extensión
/1.0/:className/:id/:extendName CORREO Crea un objeto de extensión
/1.0/:className/:id/:extendName/:rid OBTENER Leer objeto extendido
/1.0/:className/:id/:extendName/:rid PONER Modificar el objeto de extensión
/1.0/:className/:id/:extendName/:rid ELIMINAR Eliminar objeto de extensión
/1.0/:className/:id/:extendName OBTENER Consultar la lista de objetos extendidos

Establecer objeto de extensión

Establecer un objeto extendido es establecer una conexión entre dos objetos independientes. Por ejemplo, Tom ha adoptado una mascota llamada gato, lo que se puede lograr con las siguientes operaciones:

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 de cat debe especificarse en el cuerpo.

Crea un objeto de extensión

Al crear directamente objetos extendidos, puede establecer conexiones entre objetos mientras crea 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 establecerá una relación de asociación con Tom.

Leer objeto extendido

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

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

Modificar el 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 de extensión

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

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

Consultar la lista de objetos extendidos

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

ACL

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 cuando se define el modelo, equivale a establecer los permisos predeterminados:

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

cuerpo principal

Hay tres descripciones principales de ACL, usuario id, usuario roley *, idrepresentan a un usuario específico, rolelo que indica que el usuario tiene un rol, *significa que todos los usuarios:

cuerpo principal describir prioridad
identificación La identificación del usuario específico 1
papel Nombre del grupo de usuarios 2
* Todos 3

Al verificar los privilegios, el primero coincidirá con idlos derechos correspondientes, si no se especifica, los rolepermisos de usuario coincidentes correspondientes aún si se especifica, para ver si la *autoridad designada , si *tampoco se especifica, no tiene permiso.

Por ejemplo, la configuración de permisos anterior, especifica que el usergrupo de usuarios puede leer, el usuario 57fbbdb0a2400000tiene todos los derechos, mientras que otros usuarios sin ningún permiso.

Autoridad

ACL categoriza cinco tipos de permisos según el comportamiento de la API:

Autoridad describir Tipo permitido
crear Crea un objeto verdadero / falso / matriz
leer Leer objeto verdadero / falso / matriz
escribir Modificar el objeto verdadero / falso / matriz
Eliminar Eliminar objeto verdadero Falso
encontrar Lista de objetos de consulta verdadero Falso
* Coincidir con todos los permisos verdadero / falso / matriz

Permisos desarrollados truepara permitir el acceso, para falseprohibir el acceso para arraypermitir solo campos de acceso específicos. deleteY findno acepta array, si lo establece, arrayentonces se considera como true. Si el permiso especificado no existe, el siguiente coincide con la *autoridad principal . Si no existe, vuelva a consultar el tema de la siguiente prioridad.

Ejemplos del ejemplo anterior, si se requiere configurar usersolo permite la lectura titley detailse pueden leer otros title, se puede configurar de manera que:

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 objeto

Los permisos de toda la clase se establecen en el modelo. Si necesita establecer permisos para objetos específicos, puede configurar OACL para lograr:

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 sujeto, se permitirán todas las operaciones, de lo contrario se prohibirán todas las visitas. Los permisos se comprobarán de acuerdo con los siguientes pasos:

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

Permisos de objetos extendidos

El control de permisos de acceso del objeto extendido es similar al permiso de objeto básico, la única diferencia es que debe especificarse por separado en la ACL:

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, cualquier persona puede acceder a la información personal namey sex, y acceder y buscarlo libremente pets, soy el usuario que puede operar todos sus datos, y todos los derechos para tener su propia información de mascotas.

Al verificar la autoridad de acceso del objeto extendido, la autoridad del objeto y la autoridad del objeto extendido se verifican por separado. Por ejemplo, la siguiente solicitud:

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

Los permisos se comprobarán de acuerdo con los siguientes pasos:

  • 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 personalizando la función.

La gran mayoría de los permisos se pueden controlar mediante ACL y no se requiere ninguna función para completar los permisos basados ​​en objetos. 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 varios registros de la base de datos.

Dibujar el modelo de datos

Después de completar la definición de datos, se puede usar app.diagram()para dibujar svgun diagrama de clases de formato de modelo de datos , los archivos se guardarán en una imagen similar a la siguiente: diagrama