Tolles Community-Modul

fib-app

Fibjs-Anwendung grundlegendes API-Framework

Installieren

1
npm install fib-app [--save]

Prüfung

1
npm test

Erstellen Sie ein einfaches Skript

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 Typprüfung, Ereignisse usw.

API-Datenformat

Bei POST- und PUT-Anfragen muss der Hauptteil der Anfrage im JSON-Format vorliegen und der Content-Type des HTTP-Headers muss auf application/json gesetzt werden.

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 Anfragen ist das Antwortformat ein JSON-Objekt.

Der Erfolg einer Anfrage wird durch den HTTP-Statuscode angezeigt. Ein 2XX-Statuscode zeigt den Erfolg an und ein 4XX zeigt an, dass die Anforderung fehlgeschlagen ist. Wenn eine Anfrage 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 gegliedert: Die ersten drei Stellen 403 geben den Fehlertyp an, 05 die Datentabellennummer und 01 den detaillierten Fehlercode.

Bei einem GET-Request werden in der Regel die Objektdaten zurückgegeben, je nach Adresse des GET-Requests 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 besonderer Bedeutung, die nicht über die API geändert werden dürfen. Beziehungsweise id, updatedAt, createdAt, createdBy.

Dabei werden id, updatedAt, createdAteinzelne 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/:Klassenname 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/:Klassenname ERHALTEN Objektliste abfragen

Neues Objekt erstellen

Um ein neues Objekt zu erstellen, sollte eine POST-Anfrage an die URL der Klasse gesendet werden, die das Objekt selbst enthalten soll. Um beispielsweise das Objekt wie oben erwähnt zu erstellen:

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 Created, und der Hauptteil der Antwort ist ein JSON-Objekt, einschließlich der objectId und des createdAt-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 seinen Inhalt abrufen, indem Sie eine GET-Anforderung an den Speicherort des zurückgegebenen Headers senden. Um beispielsweise das oben erstellte Objekt zu erhalten:

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 keysbenutzerdefinierter Inhalt zurückgegeben werden kann keysInhalt ist in einem ,geteilten Feldnamensstrings:

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 bestehenden Daten eines Objekts zu ändern, können Sie einen PUT-Request an die entsprechende URL des Objekts senden.Ein nicht angegebener Schlüssel wird nicht geändert, sodass Sie nur eine Teilmenge der Objektdaten aktualisieren können. Ändern wir beispielsweise ein Altersfeld unseres Objekts:

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-Anfrage an die URL des angegebenen Objekts senden, z. B.:

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 ist einfach, um alle Benutzer zu erhalten:

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 Tastenfelder

Wie bei der Objektabfrage können Sie das keysbenutzerdefinierte Abfragelistenfeld festlegen, das das Ergebnis enthält. keysDer Inhalt ist in einen ,Feldnamenstring unterteilt, zum Beispiel:

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

Nur die angegebene Rückgabe nameund agezwei Felder.

wo Filterbedingung

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

whereDer Wert des Parameters sollte JSON-codiert sein. Mit anderen Worten, wenn Sie sich die tatsächlich gesendete URL-Anforderung ansehen, sollte sie zuerst JSON-codiert und dann URL-codiert sein. Am einfachsten whereals Argumente zu verwenden ist die Angabe des richtigen Schlüssels und Werts. Wenn wir beispielsweise nach Benutzern suchen möchten, deren Name tom ist, sollten wir die Abfrage wie folgt erstellen:

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

where Der Wert ist ein JSON-String nach urlencode, der Inhalt ist:{"name":"tom"}

Neben der exakten Übereinstimmung mit einem gegebenen Wert werden auch whereVergleichsmethoden wie Inklusion unterstützt. whereDie Parameter unterstützen die folgenden Optionen:

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

überspringen Datensätze ü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

order gibt die Sortiermethode an

Nach orderOptionssatz, um die Ergebnismenge zu sortieren, bevor der Feldname eine -Rückwärtszeit 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, kann gleichzeitig eine Ergebnismenge des angegebenen Inhalts zurückgegeben werden.

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 umfassen:

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 die Definition von hasOne und hasMany durch orm kann die Assoziationsbeziehung zwischen Objekten definiert und in der API widergespiegelt 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 Nebenstellenobjekt setzen
/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 Abfrage der Liste der erweiterten Objekte

Nebenstellenobjekt setzen

Durch das Setzen eines erweiterten Objekts wird eine Verbindung zwischen zwei unabhängigen Objekten hergestellt. Tom hat zum Beispiel 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

Beim Aufruf muss die ID von cat im body angegeben werden.

Erstellen Sie ein Erweiterungsobjekt

Durch direktes Erstellen von erweiterten Objekten 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 wird hergestellt.

Erweitertes Objekt lesen

Das Lesen von erweiterten Objekten 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 von erweiterten Objekten ist dem Lesen von Stammobjekten 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

Das Löschen eines erweiterten Objekts löscht nicht das Objekt selbst, sondern nur die Beziehung zwischen den Objekten:

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

Abfrage der Liste der erweiterten Objekte

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 das 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 beim Definieren des Modells keine ACL angegeben wird, entspricht dies dem Festlegen der Standardberechtigungen:

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

Hauptkörper

Es gibt drei Haupt-ACL-Beschreibungen, user id, user roleund *, idrepräsentieren einen bestimmten Benutzer und geben an role, dass der Benutzer eine Rolle hat, was *bedeutet, dass alle Benutzer:

Hauptkörper Beschreibung Priorität
Ich würde Die ID des jeweiligen Benutzers 1
Rolle Name der Benutzergruppe 2
* Alle 3

Bei der Überprüfung von Berechtigungen wird die erste mit idden entsprechenden Rechten übereinstimmen, wenn nicht angegeben, die entsprechenden Benutzerberechtigungen roleentsprechen noch, wenn angegeben, um zu sehen, ob die benannte *Autorität, falls *ebenfalls nicht angegeben, keine Berechtigung hat.

Zum Beispiel die obige Berechtigungskonfiguration, geben Sie die userBenutzergruppe lesen kann, hat der Benutzer 57fbbdb0a2400000volle Rechte, während andere Benutzer ohne Berechtigung.

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 wahr / falsch / Array
lesen Objekt lesen wahr / falsch / Array
schreiben Ändern Sie das Objekt wahr / falsch / Array
löschen Objekt löschen wahr falsch
finden Objektliste abfragen wahr falsch
* Alle Berechtigungen abgleichen wahr / falsch / Array

Berechtigungen, die entwickelt wurden true, um den Zugriff zu ermöglichen, den Zugriff zu falseverbieten, arrayum nur bestimmte Zugriffsfelder zuzulassen. deleteUnd findakzeptiert nicht array, wenn du das arraydann als setzt an true. Wenn die angegebene Berechtigung nicht vorhanden ist, dann entspricht die nächste Übereinstimmung mit der Hauptberechtigung *. Wenn keine vorhanden ist, fragen Sie den Betreff mit der nächsten Priorität erneut ab.

Beispiele für das obige Beispiel, wenn es erforderlich ist, usernur das Lesen zuzulassen titleund detailandere zu lesen 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 so einstellen, dass Folgendes erreicht wird:

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, wenn der Besucher das Subjekt ist, werden alle Operationen erlaubt, andernfalls werden alle Besuche verboten. Die Berechtigungen werden nach folgenden Schritten geprüft:

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

Erweiterte Objektberechtigungen

Die Zugriffsberechtigungssteuerung des erweiterten Objekts ähnelt der grundlegenden Objektberechtigung, der einzige Unterschied besteht darin, dass sie separat in der ACL 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 kann jeder auf persönliche Daten zugreifen können nameund sex, und den freien Zugang und suchen Sie ihn pets, ich bin der Anwender kann alle ihre Daten arbeiten, und alle Rechte , ihre eigenen Haustier Informationen zu haben.

Bei der Prü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 nach folgenden Schritten geprüft:

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

Funktion

APIs können für das Modell definiert werden und komplexe Datenoperationen können durch Anpassen der Funktion abgeschlossen werden.

Die überwiegende Mehrheit der Berechtigungen kann durch ACL gesteuert werden, und es ist keine Funktion erforderlich, um objektbasierte Berechtigungen zu vervollständigen. Die Funktion kann verwendet werden, um datenbasierte Berechtigungen zu vervollständigen, z. B. Berechtigungen an verschiedene Benutzergruppen basierend auf dem Genehmigungsstatus zu erteilen. Und mehrere Änderungen, wie die Notwendigkeit, mehrere Datenbankeinträge zu ändern.

Zeichnen Sie das Datenmodell

Nach Abschluss der Datendefinition kann ein Klassendiagramm im app.diagram()Datenmodellformat svggezeichnet werden. Die Dateien werden in einem Bild ähnlich dem folgenden gespeichert: Diagramm