Fantastisches Community-Modul

fib-app

Fibjs Application Basic API Framework

Installieren

1
npm install fib-app [--save]

Test

1
npm test

Basisskript erstellen

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

Wenn person das Modelldefinitionsmodul ist, lautet der Inhalt wie folgt:

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

Dies ist eine Standard-Orm-Definition und kann auch andere Funktionen von Orm verwenden, z. B. Typprüfung, Ereignisse usw.

API-Datenformat

Bei POST- und PUT-Anforderungen muss der Hauptteil der Anforderung im JSON-Format vorliegen und der Inhaltstyp des HTTP-Headers muss auf application / json festgelegt sein.

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

Für alle Anforderungen ist das Antwortformat ein JSON-Objekt.

Der Erfolg einer Anfrage wird durch den HTTP-Statuscode angezeigt. Ein 2XX-Statuscode zeigt Erfolg an, und ein 4XX zeigt einen Anforderungsfehler an. Wenn eine Anforderung fehlschlägt, ist der Hauptteil der Antwort immer noch ein JSON-Objekt, enthält jedoch immer zwei Felder, Code und Nachricht, die Sie zum Debuggen verwenden können. Wenn beispielsweise eine Autorisierungsanforderung fehlschlägt, werden die folgenden Informationen zurückgegeben:

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

Der Code ist in drei Teile unterteilt, die ersten drei 403 geben den Fehlertyp an, 05 die Datentabellennummer und 01 den detaillierten Fehlercode.

Bei GET-Anforderungen werden normalerweise Objektdaten zurückgegeben. Abhängig von der Adresse der GET-Anforderung kann ein Objekt oder ein Array zurückgegeben werden. Zum Beispiel:

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

Oder:

1 2 3 4 5 6 7 8 9 10 11 12
[ { "name": "tom", "sex": "male", "age": 23 }, { "name": "lily", "sex": "female", "age": 22 } ]

Spezialgebiet

Es gibt vier Felder mit speziellen Bedeutungen in den Objektdaten, die nicht über die API geändert werden dürfen. Sie sind id , updatedAt , createdAt , createdBy .

In welcher id , updatedAt , createdAt einzelnen Felder werden automatisch erstellt und geändert. createdBy muss einen eigenen Typ angeben.

Grundlegende Objektzugriffs-API

Nach Abschluss dieser Datendefinition erhalten Sie direkt eine Reihe von Schnittstellenaufrufen, die der REST-API-Spezifikation entsprechen:

URL Methode Aktion
/1.0/:className POST Neues Objekt erstellen
/1.0/:className/:id ERHALTEN Objekt lesen
/1.0/:className/:id PUT Objekt ändern
/1.0/:className/:id LÖSCHEN Objekt löschen
/1.0/:className ERHALTEN Objektliste abfragen

Neues Objekt erstellen

Um ein neues Objekt zu erstellen, sollte eine POST-Anforderung an die URL der Klasse gesendet werden, die das Objekt selbst enthalten sollte. So erstellen Sie beispielsweise das oben beschriebene Objekt:

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

Wenn die Erstellung erfolgreich ist, lautet die HTTP-Antwort 201 Erstellt, und der Hauptteil der Antwort ist ein JSON-Objekt, das die Objekt-ID und den Erstellungszeitpunkt des neuen Objekts enthält:

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

Objekt lesen

Wenn Sie ein Objekt erstellen, können Sie dessen Inhalt abrufen, indem Sie eine GET-Anforderung an den Speicherort des zurückgegebenen Headers senden. Um beispielsweise das oben erstellte Objekt abzurufen:

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

Der Körper gibt ein JSON - Objekt - Feld enthält alle Benutzer und createdAt , updatedAt und id Felder:

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

Durch die Einstellung Feld kehrt keys , individuelle Inhalte können zurückgegeben werden keys zu einem Gehalt , Segmentierung Feldnamen Strings:

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

Wird zurückkehren:

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

Objekt ändern

Um die Daten zu ändern, über die ein Objekt bereits verfügt, können Sie eine PUT-Anforderung an die entsprechende URL des Objekts senden. Jeder nicht angegebene Schlüssel wird nicht geändert, sodass Sie nur eine Teilmenge der Objektdaten aktualisieren können. Lassen Sie uns zum Beispiel ein Altersfeld unseres Objekts ändern:

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

Das zurückgegebene JSON-Objekt enthält die Felder updatedAt und id , die angeben, wann die Aktualisierung stattgefunden hat:

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

Objekt löschen

Um ein Objekt zu löschen, können Sie eine DELETE-Anforderung an die URL des angegebenen Objekts senden, z.

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

Objektliste abfragen

Sie können mehrere Objekte gleichzeitig abrufen, indem Sie eine GET-Anforderung ohne URL-Parameter an die URL der Klasse senden. Hier ist eine einfache Möglichkeit, alle Benutzer zu erreichen:

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

Der zurückgegebene Wert ist ein JSON-Objekt, das das Ergebnisfeld enthält, und sein Wert ist eine Liste von Objekten:

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

Anpassung der Schlüsselfelder

Wie bei Objektabfragen können Sie die keys festlegen, um die in den zurückgegebenen Ergebnissen enthaltenen Felder beim Abfragen der Liste anzupassen. keys eines Inhalts zu , Segmentierung Feldnamen Zeichenketten, zum Beispiel:

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

Gibt an, dass nur zwei Felder, name und age zurückgegeben werden.

wo Filter

Das Abfrageobjekt kann durch die Form des where Parameters eingeschränkt werden.

Der Wert des where Parameters sollte JSON-codiert sein. Das heißt, wenn Sie sich die tatsächlich ausgegebene URL-Anforderung ansehen, sollte sie zuerst in JSON und dann in URL codiert werden. Der einfachste Weg, den where Parameter zu verwenden, besteht darin, den erforderlichen Schlüssel und Wert anzugeben. Wenn wir beispielsweise nach einem Benutzer namens tom suchen möchten, sollten wir eine Abfrage wie folgt erstellen:

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

where ist eine JSON-Zeichenfolge nach Urlencode, der Inhalt ist: {"name":"tom"}

Neben der exakten Übereinstimmung mit einem bestimmten Wert, where auch Vergleichsmethoden wie Einschluss unterstützt. where Parameter unterstützt die folgenden Optionen:

Schlüssel Betrieb Probe
Gl Gleich {"name": {"eq": "tom"}} oder {"name": "tom"}
ne Nicht gleich {"name": {"ne": "tom"}}
gt Größer als {"age": {"gt": "24"}}
gte Größer oder gleich {"age": {"gte": "24"}}
lt Weniger als {"age": {"lt": "24"}}
lte Kleiner als oder gleich {"age": {"lte": "24"}}
wie Fuzzy-Abfrage {"name": {"like": "% m"}}
nicht wie Fuzzy-Abfrage {"name": {"not_like": "% m"}}
zwischen Intervallvergleich {"Alter": {"zwischen": [22,25]}}
not_between Intervallvergleich {"age": {"not_between": [22,25]}}
in Aufzählung {"name": {"in": ["tom", "lily"]}}
not_in Aufzählung {"name": {"not_in": ["tom", "lily"]}}
oder ODER-Betrieb {"oder": [{"Name": "Tom"}, {"Alter": 24}]}

Datensätze überspringen

Über skip Option " skip " können Sie die angegebene Anzahl von Datensätzen überspringen, um den Effekt des Umblätterns zu erzielen.

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

limit gibt das Datensatzlimit zurück

Die limit Option kann die Anzahl der zurückgegebenen Datensätze begrenzen. Die gültige limit Anzahl beträgt 1-1000 und der Standardwert ist 100.

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

order gibt die Bestellmethode an

Durch die order Option, stellen Sie die Rückgabe von Ergebnismengen sortiert werden, bevor der Feldname enthält - wenn umgekehrt.

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

count gibt die Gesamtzahl der Ergebnisse zurück

Durch Erhöhen der count beim Anfordern kann die Gesamtzahl der Ergebnismengen zurückgegeben werden, während der angegebene Inhalt zurückgegeben wird.

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

Zu diesem Zeitpunkt enthält das zurückgegebene Ergebnis zwei Felder, count und results , die die Gesamtzahl bzw. das Ergebnis enthalten:

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

Erstellen Sie erweiterte Objekte

Durch Definieren von hasOne und hasMany durch orm kann die Beziehung zwischen Objekten definiert und in der API wiedergegeben werden, zum Beispiel:

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

Erweiterte Objektzugriffs-API

Das Folgende ist die API-Definition des Erweiterungsobjekts:

URL Methode Aktion
/1.0/:className/:id/:extendName PUT Erweitertes Objekt festlegen
/1.0/:className/:id/:extendName POST Erweiterungsobjekt erstellen
/1.0/:className/:id/:extendName/:rid ERHALTEN Lesen Sie erweiterte Objekte
/1.0/:className/:id/:extendName/:rid PUT Erweiterte Objekte ändern
/1.0/:className/:id/:extendName/:rid LÖSCHEN Erweitertes Objekt löschen
/1.0/:className/:id/:extendName ERHALTEN Erweiterte Objektliste abfragen

Erweitertes Objekt festlegen

Durch Festlegen eines erweiterten Objekts wird eine Verbindung zwischen zwei unabhängigen Objekten hergestellt. Zum Beispiel hat Tom ein Haustier namens Katze adoptiert, was mit den folgenden Operationen erreicht werden kann:

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

Im Aufruf muss die ID der Katze im Körper angegeben werden.

Erweiterungsobjekt erstellen

Durch die direkte Erstellung erweiterter Objekte können Sie beim Erstellen Verbindungen zwischen Objekten herstellen. Zum Beispiel:

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

Ein Haustier namens Katze wird erstellt und mit Tom assoziiert.

Lesen Sie erweiterte Objekte

Das Lesen erweiterter Objekte ähnelt dem Lesen von Basisobjekten und unterstützt auch die Schlüsseloption:

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

Erweiterte Objekte ändern

Das Lesen erweiterter Objekte ist dem Lesen von Basisobjekten sehr ähnlich:

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

Erweitertes Objekt löschen

Durch das Löschen eines erweiterten Objekts wird das Objekt selbst nicht gelöscht, sondern nur die Beziehung zwischen den Objekten freigegeben:

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

Erweiterte Objektliste abfragen

Die erweiterte Objektliste für Abfragen ist der Basisobjektliste für Abfragen sehr ähnlich und unterstützt auch Optionen wie Schlüssel und Bedingungsfilterung:

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

ACL

Sie können die Datenberechtigungen steuern, indem Sie die ACL des Modells definieren. Zum Beispiel:

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: String, note: String }, { ACL: function(session) { return { "*": { "*": false }, "57fbbdb0a2400000": { "*": true }, "roles": { "user": { "read": true } } }; } }); };

Wenn die ACL beim Definieren des Modells nicht angegeben wird, entspricht dies dem Festlegen der Standardberechtigungen:

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

Hauptkörper

Es gibt drei Haupt ACL Beschreibung Benutzer id , Benutzer role , und * , id einen bestimmten Benutzer darstellt, role , dass der Benutzer eine Rolle hat, * steht für alle Benutzer:

Hauptkörper Beschreibung Priorität
id Spezifische Benutzer-ID 1
Rolle Benutzergruppenname 2
* * Alle 3

Wenn Berechtigungen überprüft, müssen Sie zuerst übereinstimmen id entsprechen Berechtigungen , wenn nicht anders angegeben, Benutzer passende role Behörde entspricht, wenn noch angegeben, sieht es an , ob die * Behörde, wenn * ist auch nicht anders angegeben, haben keine Berechtigung.

Die obige Berechtigungskonfiguration gibt beispielsweise an, dass die user gelesen werden kann. Benutzer 57fbbdb0a2400000 verfügt über alle Berechtigungen, während andere Benutzer keine Berechtigungen haben.

Behörde

ACL klassifiziert Berechtigungen basierend auf dem API-Verhalten in fünf Kategorien:

Behörde Beschreibung Zulässige Typen
erstellen Objekt erstellen true / false / array
lesen Objekt lesen true / false / array
schreibe Objekt ändern true / false / array
löschen Objekt löschen wahr / falsch
finden Objektliste abfragen wahr / falsch
* * Alle Berechtigungen abgleichen true / false / array

Die Berechtigungen werden auf true , um den Zugriff zuzulassen, false , um den Zugriff zu verbieten, und array um nur den Zugriff auf bestimmte Felder zuzulassen. delete und find array nicht akzeptieren, wenn array gesetzt ist, wird es als true . Wenn die angegebene Berechtigung nicht vorhanden ist, stimmt sie mit der Berechtigung * unter demselben Betreff überein. Wenn keine vorhanden sind, fragen Sie den Betreff der nächsten Priorität erneut ab.

Wenn Sie im obigen Beispiel beispielsweise festlegen müssen, dass der user nur title und detail liest und andere den title lesen können, können Sie ihn folgendermaßen einstellen:

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

Objektberechtigungen

Die Berechtigungen der gesamten Klasse werden für das Modell festgelegt. Wenn Sie Berechtigungen für bestimmte Objekte festlegen müssen, können Sie OACL festlegen, um Folgendes zu erreichen:

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 diesem Beispiel sind alle Vorgänge zulässig, wenn der Besucher der Betreff ist, andernfalls ist jeglicher Zugriff verboten. Die Berechtigungen werden gemäß den folgenden Schritten überprüft:

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

Erweiterte Objektberechtigungen

Die Zugriffsrechtssteuerung für erweiterte Objekte ähnelt den grundlegenden Objektrechten, außer dass die ACL separat angegeben werden muss:

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 dieser Definition kann jeder den name und das sex persönlicher Informationen überprüfen und seine pets frei überprüfen und durchsuchen. Der Benutzer selbst kann alle seine eigenen Daten verwalten und alle Berechtigungen für seine eigenen Haustierinformationen haben.

Bei der Überprüfung der Zugriffsrechte erweiterter Objekte werden die Objektrechte und erweiterten Objektrechte separat geprüft. Zum Beispiel die folgende Anfrage:

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

Die Berechtigungen werden gemäß den folgenden Schritten überprüft:

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

Funktion

Für Modelle können APIs definiert werden. Für komplexe Datenoperationen können benutzerdefinierte Funktionen zum Abschließen verwendet werden.

Die überwiegende Mehrheit der Berechtigungen kann über die ACL-Steuerung abgeschlossen werden, ohne dass objektbasierte Berechtigungen über die Funktion ausgeführt werden müssen. Mit dieser Funktion können datenbasierte Berechtigungen abgeschlossen werden, z. B. Berechtigungen für verschiedene Benutzergruppen basierend auf dem Genehmigungsstatus. Und viele Änderungen, z. B. die Notwendigkeit, mehrere Datenbankeinträge zu ändern.

Zeichnen Sie das Datenmodell

Nach Abschluss der Datendefinition, verwendet werden können app.diagram() Zeichendatenmodell svg - Format Klassendiagramm, wird die Datei in ein Bild ähnlich dem folgenden gespeichert werden: Diagramm