Modulo community fantastico

fib-app

framework API di base dell'applicazione fibjs

Installare

1
npm install fib-app [--save]

Test

1
npm test

Crea uno 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, person è 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 il successo e un 4XX indica il fallimento della richiesta. Quando una richiesta fallisce, il corpo della risposta è ancora un oggetto JSON, ma conterrà sempre due campi, codice e messaggio, che puoi usare per il debug. Ad esempio, se una richiesta di autenticazione dell'autorizzazione non riesce, 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 è diviso in tre parti: le prime tre cifre 403 indicano il tipo di errore, 05 indica il numero della tabella dati e 01 indica il codice di errore dettagliato.

Per le richieste GET, di solito vengono restituiti i dati dell'oggetto A seconda dell'indirizzo della richiesta GET, può essere restituito un oggetto o un array. ad 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 } ]

Campo speciale

Nei dati dell'oggetto ci sono quattro campi con un significato speciale, che non possono essere modificati tramite l'API. Sono id , updatedAt , createdAt , createdBy .

Gli id , updatedAt , createdAt singoli campi verranno automaticamente creati e modificati. createdBy deve specificare il tipo da solo.

API di accesso agli oggetti di base

Dopo aver completato questa definizione dei dati, si avrà direttamente un set completo di chiamate all'interfaccia conformi alla specifica dell'api REST:

url metodo azione
/1.0/:className INVIARE Crea nuovo oggetto
/1.0/:className/:id OTTENERE Leggi oggetto
/1.0/:className/:id METTERE Modifica oggetto
/1.0/:className/:id ELIMINA Elimina oggetto
/1.0/:className OTTENERE Elenco oggetti query

Crea 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 menzionato 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, inclusi objectId e createdAt timestamp del nuovo oggetto:

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

Leggi oggetto

Quando crei un oggetto, puoi ottenere il suo contenuto inviando una richiesta GET al percorso dell'intestazione 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ù i campi createdAt , updatedAt e 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 restituisce le keys , è possibile restituire il contenuto personalizzato, le keys di un contenuto per , stringhe del nome del campo di segmentazione:

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

Sarà di ritorno:

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

Modifica oggetto

Per modificare i dati esistenti di un oggetto, puoi inviare una richiesta PUT all'URL corrispondente dell'oggetto. Qualsiasi chiave che non hai specificato non verrà modificata, quindi puoi aggiornare solo un sottoinsieme dei dati dell'oggetto. Ad esempio, cambiamo un campo 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à i campi updatedAt e id , che indicano quando si è verificato l'aggiornamento:

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

Elimina oggetto

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

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

Elenco oggetti query

Inviando una richiesta GET all'URL della classe, senza alcun parametro URL, è possibile ottenere più oggetti contemporaneamente. Il seguente è semplicemente per ottenere tutti gli utenti:

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

Il valore restituito è un oggetto JSON contenente il campo dei risultati e il suo 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 dei campi delle chiavi

Come la query dell'oggetto, è possibile personalizzare i campi contenuti nel risultato restituito impostando le keys durante la query dell'elenco. keys di un contenuto a , stringhe del nome del campo di segmentazione, ad esempio:

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

Verrà specificato di restituire solo i due campi name ed age .

dove condizione del filtro

L'oggetto query può essere limitato sotto forma di parametro where .

Il valore del parametro where deve essere codificato in JSON. In altre parole, se guardi la richiesta URL che viene effettivamente inviata, dovrebbe essere prima codificata in JSON e poi codificata in URL. Il modo più semplice per utilizzare il parametro where è includere la chiave e il valore appropriati. Ad esempio, se vogliamo cercare utenti il ​​cui nome è tom, dovremmo costruire la query in questo modo:

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

Il valore di where è una stringa JSON dopo urlencode, il contenuto è: {"name":"tom"}

Oltre a corrispondere esattamente un dato valore, where anche supporta i metodi di confronto come inclusione. where parametro where supporta le seguenti opzioni:

chiave operazione campione
eq pari {"name": {"eq": "tom"}} o {"name": "tom"}
ne non uguale a {"name": {"ne": "tom"}}
gt più del {"age": {"gt": "24"}}
gte maggiore o uguale a {"age": {"gte": "24"}}
lt Meno di {"age": {"lt": "24"}}
lte Minore o uguale a {"age": {"lte": "24"}}
piace Query confusa {"name": {"like": "% m"}}
non come Query confusa {"name": {"not_like": "% m"}}
fra Confronto degli intervalli {"età": {"tra": [22,25]}}
non in mezzo Confronto degli intervalli {"age": {"not_between": [22,25]}}
nel enumerare {"name": {"in": ["tom", "lily"]}}
Non in enumerare {"name": {"not_in": ["tom", "lily"]}}
o Operazione OR {"or": [{"name": "tom"}, {"age": 24}]}

salta salta record

Tramite l'opzione skip , è possibile saltare il numero di record specificato per ottenere l'effetto di voltare pagina.

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

limit restituisce il limite di record

Tramite l'opzione limit , è possibile limitare il numero di record restituiti. Il numero di limit valido è 1-1000 e il valore predefinito è 100.

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

order specifica il metodo di ordinamento

Utilizzare l'opzione order per impostare il metodo di ordinamento del set di risultati restituito. Se il nome del campo contiene - prima di esso, è in ordine inverso.

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

count restituisce il numero totale di risultati

L'aumento del count durante la richiesta può restituire il numero totale di set di risultati restituendo il contenuto specificato.

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

A questo punto, il risultato restituito conterrà due campi, count e results , che contengono rispettivamente il 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" } ] }

Crea oggetti di estensione

Definendo hasOne e hasMany tramite orm, la relazione tra gli 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

Quanto segue è la definizione API dell'oggetto estensione:

url metodo azione
/1.0/:className/:id/:extendName METTERE Imposta oggetto estensione
/1.0/:className/:id/:extendName INVIARE Crea un oggetto estensione
/1.0/:className/:id/:extendName/:rid OTTENERE Leggi oggetto esteso
/1.0/:className/:id/:extendName/:rid METTERE Modifica l'oggetto estensione
/1.0/:className/:id/:extendName/:rid ELIMINA Elimina oggetto estensione
/1.0/:className/:id/:extendName OTTENERE Interroga l'elenco di oggetti estesi

Imposta oggetto estensione

L'impostazione di un oggetto esteso significa stabilire una connessione tra due oggetti indipendenti. Ad esempio, Tom ha adottato un animale domestico di nome 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 di cat deve essere specificato nel corpo.

Crea un oggetto estensione

Creando direttamente oggetti estesi, è possibile stabilire connessioni tra oggetti durante la creazione di oggetti. ad 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 di nome gatto e verrà stabilita una relazione di associazione con Tom.

Leggi oggetto esteso

La lettura di oggetti estesi è molto simile alla lettura di oggetti di base e supporta anche l'opzione chiavi:

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

Modifica l'oggetto estensione

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

L'eliminazione di un oggetto esteso non elimina l'oggetto stesso, ma rimuove 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 le chiavi e il filtro condizionale:

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

ACL

È possibile controllare le autorizzazioni dei dati definendo ACL modello. ad 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 non viene specificato alcun ACL quando viene definito il modello, è equivalente all'impostazione delle autorizzazioni predefinite:

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

corpo principale

Esistono tre tipi di descrizioni dell'oggetto ACL, id utente, role utente e * . id rappresenta un utente specifico, role rappresenta un utente con un determinato ruolo e * rappresenta tutti gli utenti:

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

Quando si controllano le autorizzazioni, si verificheranno prima le autorizzazioni id corrispondenti, se non specificate, all'autorità corrispondente al role utente corrispondente, se ancora specificato, controlla se l'autorità * , se anche * non è specificato, non dispone dell'autorizzazione.

Ad esempio, nella configurazione dei permessi di cui sopra, il gruppo user utente è specificato per essere in grado di leggere, l'utente 57fbbdb0a2400000 ha tutte le autorizzazioni, mentre gli altri utenti non hanno alcuna autorizzazione.

Autorità

ACL classifica cinque tipi di autorizzazioni in base al comportamento dell'API:

Autorità descrizione Tipo consentito
creare Crea oggetto vero / falso / matrice
leggere Leggi oggetto vero / falso / matrice
Scrivi Modifica oggetto vero / falso / matrice
Elimina Elimina oggetto vero falso
trova Elenco oggetti query vero falso
* Abbina tutte le autorizzazioni vero / falso / matrice

Le autorizzazioni sono impostate su true per consentire l'accesso, false per vietare l'accesso e array per consentire l'accesso solo ai campi specificati. delete e find non accetta array , se array è impostato, è considerato true . Se l'autorizzazione specificata non esiste, corrisponderà all'autorità * sotto lo stesso principale. Se non esiste, interrogare nuovamente l'oggetto con la priorità successiva.

Ad esempio, nell'esempio sopra, se è necessario impostare che user consentito solo leggere il title e i detail e altre persone possono leggere il title , è possibile 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 oggetto

I permessi dell'intera classe sono impostati sul Modello. Se devi impostare i permessi per oggetti specifici, puoi impostare 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 saranno consentite, altrimenti tutte le visite saranno vietate. Le autorizzazioni verranno verificate in base ai seguenti passaggi:

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

Autorizzazioni estese per gli oggetti

Il controllo dell'autorizzazione di accesso dell'oggetto esteso è simile all'autorizzazione dell'oggetto di 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 il name e il sex informazioni personali e controllare e cercare liberamente i suoi pets L'utente stesso può manipolare tutti i suoi dati e ha tutti i diritti sulle sue informazioni.

Quando si controlla l'autorizzazione di accesso dell'oggetto esteso, l'autorizzazione all'oggetto e l'autorizzazione all'oggetto esteso vengono controllate separatamente. Ad esempio, la seguente richiesta:

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

Le autorizzazioni verranno verificate in base ai seguenti passaggi:

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

Funzione

Le API possono essere definite per il Modello e le operazioni complesse sui dati possono essere completate personalizzando la Funzione.

La stragrande maggioranza delle autorizzazioni può essere controllata da ACL e non è richiesta alcuna funzione per completare le autorizzazioni basate sugli oggetti. La funzione può essere utilizzata per completare le autorizzazioni basate sui dati, come la concessione di autorizzazioni a diversi gruppi di utenti in base allo stato di approvazione. E più modifiche, come la necessità di modificare più record di database.

Disegna il modello di dati

Dopo aver completato la definizione dei dati, è possibile utilizzare app.diagram() disegnare il diagramma delle classi in formato svg del modello di dati e salvarlo nel file per ottenere un'immagine simile alla seguente:diagramma