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

In cui si persontrova il modulo di definizione del modello, come segue:

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 i due campi di 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 indicano il numero della tabella dati e 01 indicano il codice di errore dettagliato.

Per una richiesta 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 significati speciali, che non possono essere modificati tramite l'API. Rispettivamente id, updatedAt, createdAt, createdBy.

Dove id, updatedAt, createdAtsingoli campi verranno creati e modificati automaticamente. createdByDevi specificare tu stesso il tipo.

API di accesso agli oggetti di base

Dopo aver completato questa definizione dei dati, avrai 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 l'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 restituisce un oggetto JSON contiene tutti i forniti dall'utente insieme con il campo createdAt, updatedAte idcampi:

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

Restituisce il campo fornendo keys, il contenuto personalizzato può essere restituito il keyscontenuto è in ,stringhe del nome di un campo diviso:

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

Tornerà:

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

Modifica l'oggetto

Per modificare i dati esistenti di un oggetto, è possibile inviare una richiesta PUT all'URL corrispondente dell'oggetto. Qualsiasi chiave non specificata non verrà modificata, quindi è possibile 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

JSON oggetto restituito conterrà updatedAte idcampo indica l'aggiornamento si è verificato alla volta:

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

Elimina oggetto

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

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

Elenco oggetti query

Inviando una richiesta GET all'URL della classe, è possibile ottenere più oggetti contemporaneamente senza alcun parametro URL. 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 con la query dell'oggetto, è possibile impostare il keyscampo personalizzato dell'elenco query che restituisce il risultato da contenere. keysIl contenuto è in una ,stringa del nome di campo diviso, ad esempio:

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

Solo il ritorno specificato namee agedue campi.

dove condizione del filtro

By wherepuò creare vincoli sull'oggetto query come parametro.

whereIl valore del parametro deve essere codificato in JSON. In altre parole, se guardi la richiesta URL che è stata effettivamente inviata, dovrebbe essere codificata prima in JSON e poi codificata in URL. Il modo più semplice da usare wherecome argomenti è includere chiave e valore corretti. 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

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

Oltre a far corrispondere esattamente un dato valore, wheresono supportati anche metodi di confronto come l'inclusione. whereI parametri supportano 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]}}
in enumerare {"name": {"in": ["tom", "lily"]}}
Non in enumerare {"name": {"not_in": ["tom", "lily"]}}
o Operazione OR {"or": [{"name": "tom"}, {"age": 24}]}

salta salta record

Per skipopzione, è possibile specificare il numero di record da saltare, per ottenere l'effetto di capovolgimento.

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

limit restituisce il limite di record

Per limitopzione, è possibile limitare il numero di record restituiti, limitle cifre significative da 1 a 1000 e il valore predefinito a 100.

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

order specifica il metodo di ordinamento

Per orderopzione impostata per restituire Ordina set di risultati, prima che il nome del campo contenga -come tempo inverso.

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

count restituisce il numero totale di risultati

Quando viene richiesto di aumentare countil numero totale, può restituire un set di risultati del contenuto specificato allo stesso tempo.

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

A questo punto, i risultati restituiti contenenti counte resultsdue campi e ciascuno comprendente un numero totale di risultati:

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 oggetto estensione

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

Di seguito è riportata 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 degli oggetti estesi è molto simile all'interrogazione dell'elenco degli 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

I permessi dei dati possono essere controllati definendo l'ACL del 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, equivale a impostare le autorizzazioni predefinite:

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

corpo principale

Ci sono tre principali ACL descrizione, utente id, utente rolee *, idrappresentare un utente specifico, roleindicando che l'utente ha un ruolo, *significa che tutti gli utenti:

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

Quando si controllano i privilegi, il primo corrisponderà idai diritti corrispondenti, se non specificati, i rolepermessi utente corrispondenti corrispondenti ancora se specificati, per vedere se l' *autorità designata , se *anche non specificata, non dispone dell'autorizzazione.

Ad esempio, la configurazione dei permessi di cui sopra, specifica che il usergruppo di utenti può leggere, l'utente 57fbbdb0a2400000ha pieni diritti, mentre gli altri utenti senza alcuna autorizzazione.

Autorità

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

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

Autorizzazioni sviluppate trueper consentire l'accesso, per falsevietare l'accesso per arrayconsentire solo campi di accesso specificati. deleteE findnon accetta array, se si imposta arrayquindi considerato come true. Se l'autorizzazione specificata non esiste, la corrispondenza successiva con l' *autorità principale . Se non esiste, interrogare nuovamente l'oggetto della priorità successiva.

Esempi dell'esempio precedente, se è necessario impostare usersolo consente la lettura titlee detailaltri possono essere letti title, può essere impostato in modo tale che:

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

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 è il soggetto, 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); };

Questa definizione, chiunque può accedere alle informazioni personali namee sex, e l'accesso libero e cercarlo pets, io sono l'utente può utilizzare tutti i propri dati e tutti i diritti per avere le proprie informazioni sugli animali domestici.

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 il completamento della definizione dei dati può essere utilizzato app.diagram()per disegnare il svgdiagramma di classe del formato del modello di dati , i file verranno salvati in un'immagine simile alla seguente: diagramma