Fantastisches Community-Modul

fib-app

Fibjs Application Basic API Framework

Installieren

1
npm install fib-app [--save]

Prüfung

1
npm test

Erstellen Sie ein Basisskript

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

Darin personbefindet sich das Modelldefinitionsmodul 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 andere Funktionen von Orm können ebenfalls verwendet werden, wie 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 Fehler der Anforderung an. Wenn eine Anforderung fehlschlägt, ist der Hauptteil der Antwort immer noch ein JSON-Objekt, enthält jedoch immer die beiden Felder Code und Nachricht, die Sie zum Debuggen verwenden können. Wenn beispielsweise eine Anforderung zur Berechtigungsauthentifizierung 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 Ziffern 403 geben den Fehlertyp an, 05 die Datentabellennummer und 01 den detaillierten Fehlercode.

Bei einer GET-Anforderung werden die Objektdaten normalerweise zurückgegeben. Abhängig von der Adresse der GET-Anforderung kann ein Objekt oder ein Array zurückgegeben werden. sowie:

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

Spezielles Feld

In den Objektdaten gibt es vier Felder mit speziellen Bedeutungen, die nicht über die API geändert werden dürfen. Beziehungsweise id, updatedAt, createdAt, createdBy.

Wo id, updatedAt, createdAtwerden einzelne Felder automatisch erstellt und geändert. createdBySie müssen den Typ selbst angeben.

Grundlegende Objektzugriffs-API

Nach Abschluss dieser Datendefinition erhalten Sie direkt einen vollständigen Satz 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 STELLEN Ändern Sie das Objekt
/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 das Objekt wie oben beschrieben:

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, einschließlich der Objekt-ID und des erstellten Zeitstempels des neuen Objekts:

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 enthält alle Benutzer gelieferten zusammen mit dem Feld createdAt, updatedAtund idFelder:

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

Gibt das Feld zurück, indem keysbenutzerdefinierte Inhalte bereitgestellt werden. Inhalte können keysin ,geteilten Feldnamenzeichenfolgen zurückgegeben werden:

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

Wird zurückkehren:

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

Ändern Sie das Objekt

Um die vorhandenen Daten eines Objekts zu ändern, können Sie eine PUT-Anforderung an die entsprechende URL des Objekts senden. Jeder von Ihnen 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

JSON zurückgegebene Objekt enthält updatedAtund idFeld das Update aufgetreten zu einem Zeitpunkt angibt:

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

Durch Senden einer GET-Anforderung an die URL der Klasse können Sie mehrere Objekte gleichzeitig ohne URL-Parameter abrufen. Das Folgende dient einfach dazu, 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 des Schlüsselfelds

Wie bei der Objektabfrage können Sie festlegen, dass das keysbenutzerdefinierte Feld für die Abfrageliste das zu enthaltende Ergebnis zurückgibt. keysDer Inhalt ist in eine ,Feldnamenzeichenfolge unterteilt, zum Beispiel:

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

Die angegebene Rückgabe nur nameund agezwei Felder.

wo Filterbedingung

By wherekann Einschränkungen für das Abfrageobjekt als Parameter festlegen.

whereDer Wert des Parameters sollte JSON-codiert sein. Mit anderen Worten, wenn Sie sich die tatsächlich gesendete URL-Anfrage ansehen, sollte sie zuerst JSON-codiert und dann URL-codiert werden. Am einfachsten whereals Argumente zu verwenden ist es, den richtigen Schlüssel und Wert anzugeben. Wenn wir beispielsweise nach Benutzern suchen möchten, deren Name tom ist, sollten wir die Abfrage folgendermaßen erstellen:

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

where Der Wert ist eine JSON-Zeichenfolge nach Urlencode. Der Inhalt lautet:{"name":"tom"}

Neben der genauen Übereinstimmung mit einem bestimmten Wert werden auch whereVergleichsmethoden wie die Einbeziehung unterstützt. whereDie Parameter unterstützen die folgenden Optionen:

Schlüssel Betrieb Stichprobe
Gl gleich {"name": {"eq": "tom"}} oder {"name": "tom"}
ne Nicht gleichzusetzen mit {"name": {"ne": "tom"}}
gt mehr als die {"age": {"gt": "24"}}
gte größer oder gleich {"age": {"gte": "24"}}
lt Weniger als {"age": {"lt": "24"}}
lte Weniger als oder gleich {"age": {"lte": "24"}}
mögen Fuzzy-Abfrage {"name": {"like": "% m"}}
nicht wie Fuzzy-Abfrage {"name": {"not_like": "% m"}}
zwischen Intervallvergleich {"Alter": {"zwischen": [22,25]}}
nicht zwischen Intervallvergleich {"age": {"not_between": [22,25]}}
im aufzählen {"name": {"in": ["tom", "lily"]}}
nicht in aufzählen {"name": {"not_in": ["tom", "lily"]}}
oder ODER-Betrieb {"oder": [{"Name": "Tom"}, {"Alter": 24}]}

überspringen überspringen überspringen

Durch die skipOption können Sie die Anzahl der Datensätze angeben zu überspringen, Flip - Effekt zu erzielen.

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

limit gibt das Datensatzlimit zurück

Durch die limitOption können Sie die Anzahl der Datensätze zurück, begrenzen limitdie signifikanten Ziffern von 1 bis 1000 und standardmäßig auf 100.

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

Reihenfolge gibt die Sortiermethode an

Nach orderOption festlegen, um die Ergebnismenge Sortieren zurückzugeben, bevor der Feldname -als umgekehrte Zeit enthält .

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

count gibt die Gesamtzahl der Ergebnisse zurück

Wenn Sie aufgefordert werden, countdie Gesamtzahl zu erhöhen, wird möglicherweise gleichzeitig eine Ergebnismenge des angegebenen Inhalts zurückgegeben.

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

Zu diesem Zeitpunkt enthalten die Rückgabeergebnisse countund resultszwei Felder, die jeweils eine Gesamtzahl von Ergebnissen 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 ein Erweiterungsobjekt

Durch Definieren von hasOne und hasMany durch orm kann die Zuordnungsbeziehung 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 STELLEN Erweiterungsobjekt festlegen
/1.0/:className/:id/:extendName POST Erstellen Sie ein Erweiterungsobjekt
/1.0/:className/:id/:extendName/:rid ERHALTEN Erweitertes Objekt lesen
/1.0/:className/:id/:extendName/:rid STELLEN Ändern Sie das Erweiterungsobjekt
/1.0/:className/:id/:extendName/:rid LÖSCHEN Erweiterungsobjekt löschen
/1.0/:className/:id/:extendName ERHALTEN Fragen Sie die Liste der erweiterten Objekte ab

Erweiterungsobjekt festlegen

Durch das 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 Anruf muss die ID der Katze im Körper angegeben werden.

Erstellen Sie ein Erweiterungsobjekt

Durch direktes Erstellen erweiterter Objekte können Sie beim Erstellen von Objekten Verbindungen zwischen Objekten herstellen. sowie:

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 eine Assoziationsbeziehung mit Tom hergestellt.

Erweitertes Objekt lesen

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

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

Ändern Sie das Erweiterungsobjekt

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

Erweiterungsobjekt löschen

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

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

Fragen Sie die Liste der erweiterten Objekte ab

Das Abfragen der erweiterten Objektliste ist dem Abfragen der Basisobjektliste sehr ähnlich und unterstützt auch Optionen wie Schlüssel und bedingte Filterung:

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

ACL

Die Datenberechtigungen können durch Definieren der ACL des Modells gesteuert werden. sowie:

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

Wenn bei der Definition des Modells keine ACL angegeben wird, entspricht dies dem Festlegen der Standardberechtigungen:

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

Hauptkörper

Es gibt drei Hauptbeschreibungen der ACL: Benutzer id, Benutzer roleund *, iddie einen bestimmten Benutzer darstellen und roleangeben, dass der Benutzer eine Rolle hat, *bedeutet, dass alle Benutzer:

Hauptkörper Beschreibung Priorität
Ich würde Spezifische Benutzer-ID 1
Rolle Benutzergruppenname 2
* * Alles 3

Bei der Überprüfung von Berechtigungen idstimmt die erste mit den entsprechenden Rechten überein , sofern nicht angegeben, und die übereinstimmenden Benutzerberechtigungen roleentsprechen weiterhin, falls angegeben, um festzustellen, ob die angegebene *Berechtigung, falls *auch nicht angegeben, keine Berechtigung hat.

Beispiel: In der obigen Berechtigungskonfiguration wird angegeben, welche userBenutzergruppe lesen kann, der Benutzer 57fbbdb0a2400000hat die vollen Rechte, während andere Benutzer keine Berechtigung haben.

Behörde

ACL kategorisiert fünf Arten von Berechtigungen basierend auf dem API-Verhalten:

Behörde Beschreibung Zulässiger Typ
erstellen Erstellen Sie ein Objekt true / false / array
lesen Objekt lesen true / false / array
schreiben Ändern Sie das Objekt true / false / array
löschen Objekt löschen wahr falsch
finden Objektliste abfragen wahr falsch
* * Alle Berechtigungen abgleichen true / false / array

Berechtigungen, die entwickelt wurden true, um den Zugriff zu ermöglichen und den Zugriff zu falseverbieten, arrayum nur bestimmte Zugriffsfelder zuzulassen. deleteUnd findakzeptiert nicht array, wenn Sie arraydann als betrachtet betrachten true. Wenn die angegebene Berechtigung nicht vorhanden ist, stimmt die nächste mit der Hauptautorität überein *. Wenn keine vorhanden ist, fragen Sie den Betreff der nächsten Priorität erneut ab.

Beispiele für das obige Beispiel: Wenn das Festlegen usernur das Lesen zulässt titleund detailandere gelesen werden können title, kann es so eingestellt werden, dass:

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 das Thema ist, andernfalls sind alle Besuche verboten. Die Berechtigungen werden gemäß den folgenden Schritten überprüft:

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

Erweiterte Objektberechtigungen

Die Zugriffsberechtigungssteuerung des erweiterten Objekts ähnelt der grundlegenden Objektberechtigung. Der einzige Unterschied besteht darin, dass sie in der 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); };

Diese Definition, jeder kann auf persönliche Informationen zugreifen nameund sex, und freier Zugriff und Suche ihn pets, ich bin der Benutzer kann alle ihre Daten und alle Rechte, um seine eigenen Haustierinformationen zu haben.

Bei der Überprüfung der Zugriffsberechtigung des erweiterten Objekts werden die Objektberechtigung und die erweiterte Objektberechtigung getrennt 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 das Modell können APIs definiert werden, und komplexe Datenoperationen können durch Anpassen der Funktion abgeschlossen werden.

Die überwiegende Mehrheit der Berechtigungen kann von ACL gesteuert werden, und es ist keine Funktion erforderlich, um objektbasierte Berechtigungen abzuschließen. Mit dieser Funktion können datenbasierte Berechtigungen abgeschlossen werden, z. B. Berechtigungen für verschiedene Benutzergruppen basierend auf dem Genehmigungsstatus. Und mehrere Änderungen, z. B. die Notwendigkeit, mehrere Datenbankeinträge zu ändern.

Zeichnen Sie das Datenmodell

Nach Abschluss der Datendefinition können app.diagram()zum Zeichnen eines svgKlassendiagramms im Datenmodellformat Dateien in einem Bild gespeichert werden, das dem folgenden ähnelt: Diagramm