Fantastico modulo della community

fib-app

framework API di base dell'applicazione fibjs

Installare

1
npm install fib-app [--save]

Test

1
npm test

Costruisci lo script di base

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

Tra questi personc'è il modulo di definizione del modello, il contenuto è il seguente:

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

Questa è una definizione orm standard e possono essere utilizzate anche altre funzioni di orm, come il controllo del tipo, gli eventi, ecc.

Formato dati API

Per le richieste POST e PUT, il corpo della richiesta deve essere in formato JSON e il Content-Type dell'intestazione HTTP deve essere impostato su 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 tutte le richieste, il formato della risposta è un oggetto JSON.

Il successo di una richiesta è indicato dal codice di stato HTTP. Un codice di stato 2XX indica l'esito positivo, mentre un codice 4XX indica che la richiesta non è riuscita. Quando una richiesta non riesce, il corpo della risposta è ancora un oggetto JSON, ma conterrà sempre codice e campi di messaggio che puoi utilizzare per il debug. Ad esempio, se una richiesta di autorizzazione non va a buon fine, verranno restituite le seguenti informazioni:

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

Il codice del codice è diviso in tre parti, le prime tre 403 rappresentano il tipo di errore, 05 rappresenta il numero del foglio dati e 01 rappresenta il codice di errore dettagliato.

Per una richiesta GET, di solito vengono restituiti i dati dell'oggetto che, a seconda dell'indirizzo della richiesta GET, possono restituire un oggetto o un array. per esempio:

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

campi speciali

Nei dati oggetto sono presenti quattro campi con significati speciali che non possono essere modificati tramite l'API. sono id, updatedAt, , createdAt, rispettivamente createdBy.

Tra questi id, updatedAt, createdAtviene creato e modificato automaticamente un singolo campo. createdByDevi specificare tu stesso il tipo.

API di accesso agli oggetti di base

Dopo aver completato tale definizione dei dati, avrai direttamente un set di chiamate di interfaccia conformi alla specifica API REST:

URL metodo azione
/1.0/:nomeclasse INVIARE crea un nuovo oggetto
/1.0/:nomeclasse/:id OTTENERE leggi l'oggetto
/1.0/:nomeclasse/:id METTERE modificare l'oggetto
/1.0/:nomeclasse/:id ELIMINA eliminare oggetto
/1.0/:nomeclasse OTTENERE elenco degli oggetti della query

crea un nuovo oggetto

Per creare un nuovo oggetto, è necessario inviare una richiesta POST all'URL della classe, che dovrebbe contenere l'oggetto stesso. Ad esempio, per creare l'oggetto come descritto sopra:

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

Quando la creazione ha esito positivo, la risposta HTTP è 201 Created e il corpo della risposta è un oggetto JSON contenente l'objectId e il timestamp createAt del nuovo oggetto:

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

leggi l'oggetto

Quando crei un oggetto, puoi recuperarne il contenuto inviando una richiesta GET all'intestazione Location restituita. Ad esempio, per ottenere l'oggetto che abbiamo creato sopra:

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

Il corpo restituito è un oggetto JSON contenente tutti i campi forniti dall'utente più e createdAti campiupdatedAt :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" }

Impostando il campo di ritorno keysè possibile personalizzare il contenuto restituito, keysil contenuto è una stringa di nome campo ,separata da ,:

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

tornerà:

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

modificare l'oggetto

Per modificare i dati già presenti in un oggetto, puoi inviare una richiesta PUT all'URL corrispondente dell'oggetto. Eventuali chiavi non specificate non verranno modificate, quindi puoi aggiornare solo un sottoinsieme dei dati dell'oggetto. Ad esempio, cambiamo un campo di età del nostro oggetto:

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

L'oggetto JSON restituito conterrà updatedAte idi campi che indicano quando è avvenuto l'aggiornamento:

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

eliminare oggetto

Per eliminare un oggetto, inviare una richiesta DELETE all'URL dell'oggetto specificato, ad esempio:

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

elenco degli oggetti della query

Inviando una richiesta GET all'URL della classe, puoi ottenere più oggetti contemporaneamente senza alcun parametro URL. Ecco un modo semplice per ottenere tutti gli utenti:

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

Il valore restituito è un oggetto JSON contenente un campo dei risultati il ​​cui valore è un elenco di oggetti:

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

personalizzazione campo chiavi

Come per la query dell'oggetto, quando si esegue una query su un elenco, è keyspossibile . keysIl contenuto è una stringa di nomi di campo ,separati da , ad esempio:

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

specificherà nameche ageverranno restituiti solo i due campi e .

dove filtra

L'oggetto query può essere vincolato sotto forma di whereparametri .

whereIl valore del parametro deve essere codificato in JSON. Cioè, se guardi la richiesta URL effettiva che viene effettuata, dovrebbe essere prima codificata JSON, quindi codificata URL. Il modo più semplice per utilizzare un whereparametro consiste nell'includere la chiave e il valore corretti. Ad esempio, se volessimo cercare un utente chiamato tom, costruiremmo la query in questo modo:

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

whereIl valore di è una stringa JSON urlencoded con i seguenti contenuti:{"name":"tom"}

Oltre alla corrispondenza esatta di un determinato valore, wheresono supportati anche i confronti come contiene. whereIl parametro supporta le seguenti opzioni:

chiave operazione campione
eq pari {"name":{"eq":"tom"}} o {"name":"tom"}
n non uguale a {"name":{"ne":"tom"}}
gt più del {"età":{"gt":"24"}}
gte maggiore o uguale a {"age":{"gte":"24"}}
lt meno di {"età":{"lt":"24"}}
lte minore o uguale a {"età":{"lte":"24"}}
piace domanda sfocata {"name":{"like":"%m"}}
non come domanda sfocata {"name":{"not_like":"%m"}}
fra confronto a intervalli {"età":{"tra":[22,25]}}
non in mezzo confronto a intervalli {"age":{"not_between":[22,25]}}
in enumerare {"name":{"in":["tom","lily"]}}
Non in enumerare {"name":{"not_in":["tom","lily"]}}
o O operazione {"or":[{"name":"tom"},{"age":24}]}

salta salta i record

Con l' skipopzione , puoi saltare il numero specificato di record per ottenere l'effetto di girare le pagine.

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

limit restituisce il limite di record

Con l' limitopzione è possibile limitare il numero di record restituiti, limitil numero valido è 1-1000, il valore predefinito è 100.

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

order specifica il metodo di ordinamento

Tramite l' orderopzione , impostare il metodo di ordinamento del set di risultati restituito.Se il nome del campo contiene prima -di esso, sarà in ordine inverso.

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

count restituisce il numero totale di risultati

Incremento su richiesta Il numero totale di set di risultati che countpossono essere restituiti insieme al contenuto specificato.

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

A questo punto il risultato restituito conterrà counte resultsdue campi, contenenti rispettivamente il numero totale e il risultato:

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

creare oggetto di estensione

Definendo hasOne e hasMany tramite orm, l'associazione tra oggetti può essere definita e riflessa nell'API, ad esempio:

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 di accesso agli oggetti estesa

Di seguito è riportata la definizione API dell'oggetto estensione:

URL metodo azione
/1.0/:nomeclasse/:id/:nomeestensione METTERE imposta l'oggetto estensione
/1.0/:nomeclasse/:id/:nomeestensione INVIARE Crea oggetto estensione
/1.0/:ClassName/:id/:extendName/:rid OTTENERE leggere l'oggetto di estensione
/1.0/:ClassName/:id/:extendName/:rid METTERE Modifica oggetto estensione
/1.0/:ClassName/:id/:extendName/:rid ELIMINA elimina l'oggetto estensione
/1.0/:nomeclasse/:id/:nomeestensione OTTENERE Interroga l'elenco di oggetti estesi

imposta l'oggetto estensione

L'impostazione di un oggetto estensione significa stabilire una relazione tra due oggetti indipendenti. Ad esempio, Tom adotta un animale domestico chiamato gatto, che può essere ottenuto con le seguenti operazioni:

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

Nella chiamata, l'id del gatto deve essere specificato nel corpo.

Crea oggetto estensione

Creando direttamente un oggetto di estensione, è possibile stabilire la connessione tra gli oggetti durante la creazione dell'oggetto. per esempio:

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

Verrà creato un animale domestico chiamato gatto e associato a Tom.

leggere l'oggetto di estensione

La lettura di un oggetto di estensione è molto simile alla lettura di un oggetto di base e supporta anche l'opzione chiavi:

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

Modifica oggetto estensione

La lettura di un oggetto di estensione è molto simile alla lettura di un oggetto di 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

elimina l'oggetto estensione

L'eliminazione di un oggetto estensione non elimina l'oggetto stesso, dissolve solo la relazione tra gli oggetti:

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

Interroga l'elenco di oggetti estesi

L'interrogazione dell'elenco di oggetti esteso è molto simile all'interrogazione dell'elenco di oggetti di base e supporta anche opzioni come chiavi e filtro condizionale:

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

ACL

Le autorizzazioni dei dati possono essere controllate definendo l'ACL del modello. per esempio:

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 } } }; } }); };

Se si definisce Modello senza specificare ACL, equivale a impostare le autorizzazioni predefinite:

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

corpo principale

Esistono tre tipi di descrizioni dei soggetti ACL: utente id, utente rolee *, che idrappresentano un utente specifico, un utente rolecon un determinato ruolo e *tutti gli utenti:

corpo principale descrivere priorità
id ID utente specifico 1
ruolo Nome del gruppo di utenti 2
* tutto 3

Quando si controllano le autorizzazioni, corrisponderà prima alle autorizzazioni idcorrispondenti . Se non è specificato, corrisponderà rolealle autorizzazioni corrispondenti all'utente. Se è ancora specificato, verificare se *le autorizzazioni di sono specificate. Se *non è specificato, c'è nessun permesso.

Ad esempio, la configurazione delle autorizzazioni sopra specifica che il gruppo userutenti può leggere, l'utente 57fbbdb0a2400000dispone di tutte le autorizzazioni e gli altri utenti non dispongono di autorizzazioni.

autorizzazione

ACL classifica le autorizzazioni in cinque categorie in base al comportamento dell'API:

autorizzazione descrivere tipo consentito
creare creare oggetto vero/falso/matrice
leggere leggi l'oggetto vero/falso/matrice
scrivere modificare l'oggetto vero/falso/matrice
Elimina eliminare oggetto vero falso
trova elenco degli oggetti della query vero falso
* corrisponde a tutte le autorizzazioni vero/falso/matrice

Le autorizzazioni sono formulate trueper consentire l'accesso, falseper vietare l'accesso, arrayper consentire l'accesso solo a campi specificati. deletee findnon sono accettati array, e arraysono true. Se l'autorizzazione specificata non esiste, corrisponderà alle *autorizzazioni . Se non esiste, interroga nuovamente l'oggetto della priorità successiva.

Ad esempio, nell'esempio sopra, se devi impostare Consenti usersolo lettura titlee detail, altri possono leggere title, puoi impostarlo in questo modo:

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

Autorizzazioni per gli oggetti

Le autorizzazioni dell'intera classe sono impostate sul modello Se è necessario impostare autorizzazioni per oggetti specifici, è possibile impostare l'OACL per ottenere:

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; } }); };

In questo esempio, quando il visitatore è l'oggetto stesso, tutte le operazioni sono consentite, altrimenti è vietato qualsiasi accesso. Le autorizzazioni vengono verificate come segue:

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

Autorizzazioni oggetti estese

Il controllo di accesso dell'oggetto esteso è simile a quello dell'oggetto base, l'unica differenza è che deve essere specificato separatamente nell'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); };

In questa definizione, chiunque può controllare la namesomma sex, controllare e ricercare liberamente le proprie informazioni personali.L'utente petsstesso può gestire tutti i propri dati e avere tutti i permessi delle informazioni del proprio animale domestico.

Quando si controllano i diritti di accesso per gli oggetti estesi, i diritti dell'oggetto e i diritti dell'oggetto estesi vengono verificati separatamente. Ad esempio la seguente richiesta:

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

Le autorizzazioni vengono verificate come segue:

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

Funzione

Le API possono essere definite per i modelli e complesse operazioni sui dati possono essere eseguite personalizzando le funzioni.

La stragrande maggioranza delle autorizzazioni può essere controllata da ACL e le autorizzazioni basate su oggetti non devono essere eseguite tramite Function. La funzione può essere utilizzata per completare le autorizzazioni basate sui dati, ad esempio concedere autorizzazioni a diversi gruppi di utenti in base allo stato di approvazione. E una serie di modifiche, come la necessità di modificare più record di database.

Traccia il modello di dati

Dopo aver completato la definizione dei dati, è possibile app.diagram()utilizzare il svgdiagramma di classe Format per disegnare il modello di dati e salvarlo in un file per ottenere un'immagine simile alla seguente: diagramma