Mòdul comunitari fantàstic

aplicació fib

marc d'api bàsic de l'aplicació fibjs

Instal·lar

1
npm install fib-app [--save]

Prova

1
npm 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 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();

On persones troba el mòdul de definició del model, el contingut és el següent:

1 2 3 4 5 6 7
module.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 4
curl -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, updatedAtes createdAtcrearan i es modificaran automàticament camps únics. createdByHeu 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 4
curl -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:

1
curl -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, updatedAti :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, keysque és una ,cadena de noms de camp separats per:

1
curl -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 4
curl -X PUT \ -H "Content-Type: application/json" \ -d '{"age": 25}' \ http://localhost/1.0/person/57fbbdb0a2400000

L'objecte JSON retornat contindrà updatedAtcamps idque 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:

1
curl -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:

1
curl -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 keyspersonalitzar els camps inclosos als resultats retornats configurant-los quan consulteu la llista. keysEl contingut és una ,cadena de noms de camp separats per , per exemple:

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

Especificarà que només es retornaran els camps namei .age

on la condició del filtre

whereL'objecte de consulta es pot restringir en forma de paràmetres.

whereEl 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 wheremanera 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:

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

whereEl valor és una cadena JSON codificada per url, el contingut és:{"name":"tom"}

A més de fer coincidir exactament un valor determinat, wheretambé s'admeten mètodes de comparació com ara la inclusió. whereEls 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 skipl'opció, podeu saltar el nombre especificat de registres per aconseguir l'efecte de passar pàgina.

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

limit retorna el límit de registre

Mitjançant limitl'opció, podeu limitar el nombre de registres retornats. limitEls números vàlids són 1-1000 i el valor predeterminat és 100.

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

L'ordre especifica el mètode d'ordenació

Utilitzeu orderl'opció per establir el mètode d'ordenació del conjunt de resultats retornats. Quan el nom del camp conté abans, -és en ordre invers.

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

count retorna el nombre total de resultats

Incrementat a petició countEl nombre total de conjunts de resultats que es poden retornar mentre es retorna el contingut especificat.

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

En aquest moment, el resultat retornat contindrà dos camps: counti 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 9
module.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 4
curl -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 4
curl -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:

1
curl -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 4
curl -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:

1
curl -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:

1
curl -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 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 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 rolei *, idque representen un usuari específic, rolerepresenten 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 idels permisos corresponents. Si no s'especifica, coincideix amb roleels 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, users'especifica el grup d'usuaris perquè pugui llegir. L'usuari 57fbbdb0a2400000té 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 trueper permetre l'accés, falseper denegar l'accés i arraynomés per permetre l'accés als camps especificats. deletei findno s'accepten i es tracten igual arraysi 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.arraytrue*

Per exemple, a l'exemple anterior, si necessiteu configurar usernomés llegir titlei detailpermetre 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 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 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 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 aquesta definició, qualsevol persona pot comprovar la namesuma de la informació personal sexi 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:

1
curl -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: diagrama