aplicació fib
marc d'api bàsic de l'aplicació fibjs
Instal·lar
1npm install fib-app [--save]
Prova
1npm test
Crea un guió bàsic
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();
On person
es troba el mòdul de definició del model, el contingut és el següent:
1
2
3
4
5
6
7module.exports = db => {
db.define('person', {
name: String,
sex: ["male", "female"],
age: Number
});
};
Aquesta és una definició ORM estàndard, i també podeu utilitzar altres funcions ORM, com ara la comprovació de tipus, esdeveniments, etc.
Format de dades de l'API
Per a les sol·licituds POST i PUT, el cos de la sol·licitud ha d'estar en format JSON i el tipus de contingut de la capçalera HTTP s'ha d'establir 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
Per a totes les sol·licituds, el format de resposta és un objecte JSON.
El codi d'estat HTTP indica si una sol·licitud ha tingut èxit o no. Un codi d'estat 2XX indica èxit, mentre que un codi d'estat 4XX indica que la sol·licitud ha fallat. Quan una sol·licitud falla, el cos de la resposta continua sent un objecte JSON, però sempre conté els camps de codi i missatge, que podeu utilitzar per a la depuració. Per exemple, si una sol·licitud d'autenticació de permís falla, es retornarà la informació següent:
1
2
3
4{
"code": 4030501,
"message": "The operation isn’t allowed for clients due to class-level permissions."
}
El codi de codi es divideix en tres parts. Els tres primers dígits 403 representen el tipus d'error, 05 representa el número de full de dades i 01 representa el codi d'error detallat.
Per a les sol·licituds GET, normalment es retornen les dades de l'objecte. Depenent de l'adreça de la sol·licitud GET, es pot retornar un objecte o una matriu. per exemple:
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
}
]
camps especials
A les dades de l'objecte, hi ha quatre camps amb significats especials que no es poden canviar mitjançant l'API. Són id
, updatedAt
, createdAt
, respectivament createdBy
.
Entre ells id
, updatedAt
es createdAt
crearan i es modificaran automàticament camps únics. createdBy
Heu d'especificar el tipus vosaltres mateixos.
API bàsica d'accés a objectes
Després de completar aquesta definició de dades, tindreu directament un conjunt de trucades d'interfície que compleixen amb l'especificació de l'API REST:
url | mètode | acció |
---|---|---|
/1.0/:className | PUBLICACIÓ | Crea un objecte nou |
/1.0/:className/:id | ACONSEGUIR | Llegir objecte |
/1.0/:className/:id | POSAR | Modifica l'objecte |
/1.0/:className/:id | ELIMINAR | Suprimeix l'objecte |
/1.0/:className | ACONSEGUIR | Consulta la llista d'objectes |
Crea un objecte nou
Per crear un objecte nou, s'ha d'enviar una sol·licitud POST a l'URL de la classe, que hauria d'incloure l'objecte en si. Per exemple, per crear l'objecte que es mostra a dalt:
1
2
3
4curl -X POST \
-H "Content-Type: application/json" \
-d '{"name": "tom","sex":"male","age":23}' \
http://localhost/1.0/person
Quan la creació té èxit, el retorn HTTP és 201 Created, i el cos de la resposta és un objecte JSON que conté l'objectId i createdAt timestamp de l'objecte nou:
1
2
3
4{
"createdAt": "2017-11-25T01:39:35.931Z",
"id": "57fbbdb0a2400000"
}
Llegir objecte
Quan creeu un objecte, podeu recuperar-ne el contingut enviant una sol·licitud GET a la ubicació de la capçalera retornada. Per exemple, per obtenir l'objecte que hem creat anteriorment:
1curl -X GET http://localhost/1.0/person/57fbbdb0a2400000
El cos retornat és un objecte JSON que conté tots els camps proporcionats per l'usuari més els camps createdAt
, updatedAt
i :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"
}
En configurar el camp de retorn keys
, podeu personalitzar el contingut retornat, keys
que és una ,
cadena de noms de camp separats per:
1curl -X GET http://localhost/1.0/person/57fbbdb0a2400000?keys=name%2Csex
tornarà:
1
2
3
4{
"name": "tom",
"sex": "male"
}
Modifica l'objecte
Per canviar les dades existents d'un objecte, podeu enviar una sol·licitud PUT a l'URL corresponent de l'objecte. Les claus que no especifiqueu no es canviaran, de manera que només podeu actualitzar un subconjunt de les dades de l'objecte. Per exemple, canviem un camp d'edat del nostre objecte:
1
2
3
4curl -X PUT \
-H "Content-Type: application/json" \
-d '{"age": 25}' \
http://localhost/1.0/person/57fbbdb0a2400000
L'objecte JSON retornat contindrà updatedAt
camps id
que indiquen quan es va produir l'actualització:
1
2
3
4{
"updatedAt": "2017-11-25T01:39:35.931Z",
"id": "57fbbdb0a2400000"
}
Suprimeix l'objecte
Per suprimir un objecte, podeu enviar una sol·licitud DELETE a l'URL de l'objecte especificat, per exemple:
1curl -X DELETE http://localhost/1.0/person/57fbbdb0a2400000
Consulta la llista d'objectes
Podeu obtenir diversos objectes alhora enviant una sol·licitud GET a l'URL de la classe, sense cap paràmetre d'URL. A continuació s'explica com aconseguir simplement tots els usuaris:
1curl -X GET http://localhost/1.0/person
El valor retornat és un objecte JSON que conté el camp de resultats, el valor del qual és una llista d'objectes:
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"
}
]
personalització del camp de claus
Igual que la consulta d'objectes, podeu keys
personalitzar els camps inclosos als resultats retornats configurant-los quan consulteu la llista. keys
El contingut és una ,
cadena de noms de camp separats per , per exemple:
1curl -X GET http://localhost/1.0/person?keys=name%2Cage
Especificarà que només es retornaran els camps name
i .age
on la condició del filtre
where
L'objecte de consulta es pot restringir en forma de paràmetres.
where
El valor del paràmetre ha de ser codificat en JSON. És a dir, si observeu la sol·licitud d'URL real que s'està realitzant, primer hauria d'estar codificada amb JSON i després codificada per URL. La where
manera més senzilla d'utilitzar els paràmetres és incloure la clau i el valor adequats. Per exemple, si volguéssim cercar usuaris anomenats tom, construiríem la consulta com aquesta:
1curl -X GET http://localhost/1.0/person?where=%7B%22name%22%3A%22tom%22%7D
where
El valor és una cadena JSON codificada per url, el contingut és:{"name":"tom"}
A més de fer coincidir exactament un valor determinat, where
també s'admeten mètodes de comparació com ara la inclusió. where
Els paràmetres admeten les opcions següents:
clau | funcionament | mostra |
---|---|---|
eq | igual | {"name":{"eq":"tom"}} o {"name":"tom"} |
ne | no igual a | {"name":{"ne":"tom"}} |
gt | més que el | {"age":{"gt":"24"}} |
gte | major o igual a | {"age":{"gte":"24"}} |
lt | menys que | {"edat":{"lt":"24"}} |
lte | inferior o igual a | {"edat":{"lte":"24"}} |
M'agrada | consulta difusa | {"name":{"like":"%m"}} |
no_m'agrada | consulta difusa | {"name":{"not_like":"%m"}} |
entre | Comparació d'intervals | {"edat":{"entre":[22,25]}} |
no_entre | Comparació d'intervals | {"edat":{"not_entre":[22,25]}} |
en | enumerar | {"name":{"in":["tom","lily"]}} |
no_dins | enumerar | {"name":{"not_in":["tom","lily"]}} |
o | O funcionament | {"o":[{"nom":"tom"},{"edat":24}]} |
saltar registres
Mitjançant skip
l'opció, podeu saltar el nombre especificat de registres per aconseguir l'efecte de passar pàgina.
1curl -X GET http://localhost/1.0/person?skip=100
limit retorna el límit de registre
Mitjançant limit
l'opció, podeu limitar el nombre de registres retornats. limit
Els números vàlids són 1-1000 i el valor predeterminat és 100.
1curl -X GET http://localhost/1.0/person?limit=100
L'ordre especifica el mètode d'ordenació
Utilitzeu order
l'opció per establir el mètode d'ordenació del conjunt de resultats retornats. Quan el nom del camp conté abans, -
és en ordre invers.
1curl -X GET http://localhost/1.0/person?order=-id
count retorna el nombre total de resultats
Incrementat a petició count
El nombre total de conjunts de resultats que es poden retornar mentre es retorna el contingut especificat.
1curl -X GET http://localhost/1.0/person?count=1&limit=1
En aquest moment, el resultat retornat contindrà dos camps: count
i results
, que contenen el nombre total i el resultat respectivament:
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 objecte d'extensió
En definir hasOne i hasMany mitjançant ORM, podeu definir l'associació entre objectes i reflectir-la a l'API, per exemple:
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 d'accés a objectes estès
A continuació es mostra la definició de l'API de l'objecte d'extensió:
url | mètode | acció |
---|---|---|
/1.0/:className/:id/:extendName | POSAR | Estableix l'objecte d'extensió |
/1.0/:className/:id/:extendName | PUBLICACIÓ | Crea un objecte d'extensió |
/1.0/:className/:id/:extendName/:rid | ACONSEGUIR | Llegir l'objecte d'extensió |
/1.0/:className/:id/:extendName/:rid | POSAR | Modifica l'objecte d'extensió |
/1.0/:className/:id/:extendName/:rid | ELIMINAR | Suprimeix l'objecte estès |
/1.0/:className/:id/:extendName | ACONSEGUIR | Consulta la llista d'objectes ampliada |
Estableix l'objecte d'extensió
Establir un objecte d'extensió és establir una relació entre dos objectes independents. Per exemple, si Tom adopta una mascota anomenada gat, pot fer servir les operacions següents per aconseguir-ho:
1
2
3
4curl -X PUT \
-H "Content-Type: application/json" \
-d '{"id": "57fbbdb0a2400007"}' \
http://localhost/1.0/person/57fbbdb0a2400000/pets
A la trucada, cal especificar l'identificador del gat al cos.
Crea un objecte d'extensió
La creació directa d'objectes ampliats pot establir connexions entre objectes mentre es creen. per exemple:
1
2
3
4curl -X POST \
-H "Content-Type: application/json" \
-d '{"name": "cat"}' \
http://localhost/1.0/person/57fbbdb0a2400000/pets
Es crearà una mascota anomenada gat i s'associarà amb Tom.
Llegir l'objecte d'extensió
La lectura d'objectes ampliats és molt semblant a la lectura d'objectes bàsics i també admet l'opció de tecles:
1curl -X GET http://localhost/1.0/person/57fbbdb0a2400000/pets/57fbbdb0a2400007
Modifica l'objecte d'extensió
La lectura d'objectes estesos és molt semblant a la lectura d'objectes bàsics:
1
2
3
4curl -X PUT \
-H "Content-Type: application/json" \
-d '{"name": "cat 1"}' \
http://localhost/1.0/person/57fbbdb0a2400000/pets/57fbbdb0a2400007
Suprimeix l'objecte estès
La supressió d'un objecte estès no suprimeix l'objecte en si, només dissol la relació entre els objectes:
1curl -X DETELE http://localhost/1.0/person/57fbbdb0a2400000/pets/57fbbdb0a2400007
Consulta la llista d'objectes ampliada
Consultar la llista d'objectes estesa és molt semblant a consultar la llista d'objectes bàsics i també admet opcions com ara claus i filtratge condicional:
1curl -X GET http://localhost/1.0/person/57fbbdb0a2400000/pets
ACL
Els permisos de dades es poden controlar definint l'ACL del model. per exemple:
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 s'especifica cap ACL en definir el model, és equivalent a establir els permisos per defecte:
1
2
3
4
5{
"*": {
"*": true
}
}
cos principal
Hi ha tres tipus de descripcions d'assumptes d'ACL: usuari id
, usuari role
i *
, id
que representen un usuari específic, role
representen usuaris amb una funció determinada i *
representen tots els usuaris:
cos principal | descriure | prioritat |
---|---|---|
ID | identificador d'usuari específic | 1 |
paper | Nom del grup d'usuaris | 2 |
* | Tots | 3 |
Quan comproveu els permisos, primer coincidirà amb id
els permisos corresponents. Si no s'especifica, coincideix amb role
els permisos corresponents de l'usuari. Si encara s'especifica, comproveu si *
s'especifiquen els permisos de. Si *
no s'especifica, no hi ha permís.
Per exemple, a la configuració de permisos anterior, user
s'especifica el grup d'usuaris perquè pugui llegir. L'usuari 57fbbdb0a2400000
té tots els permisos, però els altres usuaris no en tenen cap.
Permisos
ACL classifica els permisos en cinc categories segons el comportament de l'API:
Permisos | descriure | tipus permesos |
---|---|---|
crear | Crea objecte | vertader/fals/matriu |
llegir | Llegir objecte | vertader/fals/matriu |
escriure | Modifica l'objecte | vertader/fals/matriu |
esborrar | Suprimeix l'objecte | vertader/fals |
trobar | Consulta la llista d'objectes | vertader/fals |
* | Coincideix amb tots els permisos | vertader/fals/matriu |
Els permisos s'estableixen true
per permetre l'accés, false
per denegar l'accés i array
només per permetre l'accés als camps especificats. delete
i find
no s'accepten i es tracten igual array
si s'estableixen . Si no existeix el permís especificat, es coincidiran amb els permisos del mateix tema. Si no n'hi ha, torneu a consultar el tema del següent nivell de prioritat.array
true
*
Per exemple, a l'exemple anterior, si necessiteu configurar user
només llegir title
i detail
permetre que els altres llegeixin title
, podeu configurar-lo així:
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 d'objectes
Els permisos establerts al Model són els permisos de tota la classe. Si necessiteu establir permisos per a objectes específics, podeu fer-ho configurant 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 aquest exemple, quan el visitant és el mateix objecte, es permetran totes les operacions, en cas contrari es prohibirà tot accés. Els permisos es comproven de la següent manera:
person[57fbbdb0a2400000]
=>OACL
person
=>ACL
Permisos d'objectes ampliats
El control de permisos d'accés dels objectes ampliats és similar als permisos dels objectes bàsics. L'única diferència és que l'ACL s'ha d'especificar per separat:
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 aquesta definició, qualsevol persona pot comprovar la name
suma de la informació personal sex
i consultar-la i buscar-la lliurement pets
. El mateix usuari pot operar amb totes les seves pròpies dades i disposar de tots els permisos per a la informació de la seva mascota.
Quan es comproven els permisos d'accés per a objectes ampliats, els permisos d'objectes i els permisos d'objectes ampliats es comproven per separat. Per exemple, la petició següent:
1curl -X GET http://localhost/1.0/person/57fbbdb0a2400000/pets/57fbbdb0a2400007
Els permisos es comproven de la següent manera:
pets[57fbbdb0a2400007]
=>OACL
person[57fbbdb0a2400000]
=>OACL
=>extends
=>pets
person
=>ACL
=>extends
=>pets
pets
=>ACL
Funció
Es poden definir API per al model i es poden completar operacions de dades complexes mitjançant funcions personalitzades.
La majoria dels permisos es poden controlar mitjançant ACL, i els permisos basats en objectes no cal que s'implementin mitjançant Function. La funció es pot utilitzar per completar permisos basats en dades, com ara concedir permisos a diferents grups d'usuaris en funció de l'estat d'aprovació. I múltiples modificacions, com ara la necessitat de modificar diversos registres de bases de dades.
Dibuixa un model de dades
Després de completar la definició de dades, podeu utilitzar per app.diagram()
dibuixar el diagrama de classes de format del model de dades svg
. Quan deseu en un fitxer, obtindreu una imatge semblant a la següent: