aplicación de mentira
marco API básico de la aplicación fibjs
Instalar
1npm install fib-app [--save]
Prueba
1npm 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
21const 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 person
está el módulo de definición de modelo? El contenido es el siguiente:
1
2
3
4
5
6
7module.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
4curl -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
, updatedAt
los createdAt
campos individuales se crearán y modificarán automáticamente. createdBy
Debe 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
4curl -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:
1curl -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 createdAt
y :updatedAt
id
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, keys
que es una ,
cadena de nombres de campos separados por:
1curl -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
4curl -X PUT \
-H "Content-Type: application/json" \
-d '{"age": 25}' \
http://localhost/1.0/person/57fbbdb0a2400000
El objeto JSON devuelto contendrá updatedAt
campos id
que 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:
1curl -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:
1curl -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 keys
personalizar los campos incluidos en los resultados devueltos configurándolos al consultar la lista. keys
El contenido es una ,
cadena de nombres de campos separados por, por ejemplo:
1curl -X GET http://localhost/1.0/person?keys=name%2Cage
Especificará que solo se devolverán los campos name
y .age
donde condición del filtro
where
El objeto de consulta se puede restringir en forma de parámetros.
where
El 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 where
forma 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í:
1curl -X GET http://localhost/1.0/person?where=%7B%22name%22%3A%22tom%22%7D
where
El valor es una cadena JSON codificada en URL, el contenido es:{"name":"tom"}
Además de hacer coincidir exactamente un valor determinado, where
también se admiten métodos de comparación como la inclusión. where
Los 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 skip
de la opción, puede omitir la cantidad especificada de registros para lograr el efecto de pasar página.
1curl -X GET http://localhost/1.0/person?skip=100
límite de retornos límite de registro
A través limit
de la opción, puede limitar la cantidad de registros devueltos. limit
Los números válidos son del 1 al 1000 y el valor predeterminado es 100.
1curl -X GET http://localhost/1.0/person?limit=100
orden especifica el método de clasificación
Utilice order
la 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.
1curl -X GET http://localhost/1.0/person?order=-id
count devuelve el número total de resultados
Incrementado a petición count
El número total de conjuntos de resultados que se pueden devolver al devolver el contenido especificado.
1curl -X GET http://localhost/1.0/person?count=1&limit=1
En este momento, el resultado devuelto contendrá dos campos: count
y 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
9module.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
4curl -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
4curl -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:
1curl -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
4curl -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:
1curl -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:
1curl -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
25const orm = require('fib-orm');
module.exports = db => {
db.define('blog', {
title: String,
detail: String,
note: 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 role
y *
, id
que representan a un usuario específico, role
representan 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 id
los permisos correspondientes. Si no se especifica, luego coincidirá con role
los 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, user
se especifica que el grupo de usuarios puede leer. El usuario 57fbbdb0a2400000
tiene 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 true
para permitir el acceso, false
denegar el acceso y array
solo permitir el acceso a campos específicos. delete
y find
no se aceptan y se tratan de la misma manera array
si 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.array
true
*
Por ejemplo, en el ejemplo anterior, si necesita configurar user
solo lectura title
y detail
permitir 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
24module.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
41module.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 name
suma de información personal sex
y 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:
1curl -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: