Teil 5. Erstellen einer REST-API: Paginierung, manuelle Sortierung und FilterungIm
vorherigen Artikel haben Sie die Kernfunktionalität der CRUD-API erstellt.
Wenn jetzt eine HTTP-GET-Anforderung auf der Mitarbeiterroute ausgegeben wird, werden alle Zeilen der Tabelle zurückgegeben. Dies mag bei nur 107 Zeilen in der Tabelle HR.EMPLOYEES nicht viel ausmachen, aber stellen Sie sich vor, was passieren würde, wenn die Tabelle Tausende oder Millionen von Zeilen enthält. Clients wie Mobil- und Webanwendungen zeigen normalerweise nur einen Bruchteil der in der Datenbank verfügbaren Zeilen an und wählen dann bei Bedarf weitere Zeilen aus - möglicherweise, wenn der Benutzer bei einer Unterbrechungssteuerung nach unten scrollt oder auf die Schaltfläche „Weiter“ klickt zu Seiten in der Benutzeroberfläche.
Zu diesem Zweck müssen REST-APIs Paginierungswerkzeuge für zurückgegebene Ergebnisse unterstützen. Sobald die Paginierung unterstützt wird, sind Sortierfunktionen erforderlich, da Daten normalerweise sortiert werden sollten, bevor die Paginierung angewendet wird. Darüber hinaus ist das Datenfilter-Tool für die Leistung sehr wichtig. Warum Daten aus der Datenbank über die Zwischenschicht und vollständig an den Client senden, wenn dies nicht erforderlich ist?
Ich werde die URL-Abfragezeichenfolgenparameter verwenden, damit Clients angeben können, wie die Ergebnisse paginiert, sortiert und gefiltert werden sollen. Wie immer bei der Programmierung kann die Implementierung abhängig von Ihren Anforderungen, Leistungszielen usw. variieren. In diesem Beitrag werde ich Ihnen einen manuellen Ansatz zum Hinzufügen dieser Funktionen zur API erläutern.
PaginierungAbfragezeichenfolgenparameter, die ich für die Paginierung verwenden werde: Überspringen und Begrenzen. Der Parameter skip wird verwendet, um die angegebene Anzahl von Zeilen zu überspringen, während limit die Anzahl der zurückgegebenen Zeilen begrenzt. Ich werde den Standardwert 30 für das Limit verwenden, wenn der Client den Wert nicht angibt.
Aktualisieren Sie zunächst die Controller-Logik, um Werte aus der Abfragezeichenfolge zu extrahieren und an die Datenbank-API zu übergeben. Öffnen Sie die Datei
controller / employee.js und fügen Sie der Funktion get nach der Zeile, in der der Parameter req.params.id analysiert wird, die folgenden Codezeilen hinzu.
Jetzt müssen Sie die Datenbanklogik aktualisieren, um diese Werte zu berücksichtigen, und die SQL-Abfrage entsprechend aktualisieren. In SQL wird die Offset-Klausel zum Überspringen von Zeilen und die Abrufklausel zum Begrenzen der Anzahl der von der Abfrage zurückgegebenen Zeilen verwendet. Wie üblich werden Werte nicht direkt zur Abfrage hinzugefügt, sondern aus Leistungs- und Sicherheitsgründen als Bindevariablen hinzugefügt. Öffnen Sie
db_apis / employee.js und fügen Sie nach dem if-Block in der
Suchfunktion den folgenden Code hinzu, der der Anforderung die where-Klausel hinzufügt.
Das ist alles was Sie tun müssen, um zu paginieren! Starten Sie die API und führen Sie dann einige URL-Befehle in einem anderen Terminal aus, um sie zu testen. Hier sind einige Beispiele, die Sie verwenden können:
# use default limit (30) curl "http://localhost:3000/api/employees" # set limit to 5 curl "http://localhost:3000/api/employees?limit=5" # use default limit and set skip to 5 curl "http://localhost:3000/api/employees?skip=5" # set both skip and limit to 5 curl "http://localhost:3000/api/employees?skip=5&limit=5"
SortierenKunden sollten mindestens in der Lage sein, eine Spalte zum Sortieren und Sortieren anzugeben (aufsteigend oder absteigend). Der einfachste Weg, dies zu tun, besteht darin, einen Abfrageparameter zu definieren (ich verwende sort), mit dem Sie eine Zeichenfolge wie 'Nachname: Aufstieg' oder 'Gehalt: Abstieg' übergeben können. Die einzige Möglichkeit, die Reihenfolge der von der SQL-Abfrage zurückgegebenen Ergebnismenge zu gewährleisten, besteht darin, die order by-Klausel einzuschließen. Aus diesem Grund wäre es schön, eine Standardauftragsdefinition zu definieren, um die Konsistenz sicherzustellen, wenn der Client sie nicht angibt.
Gehen Sie zurück zu
controller / employee.js und fügen Sie der get-Funktion nach der Zeile, in der der Parameter req.query.limit analysiert wird, die folgende Codezeile hinzu.
Öffnen
Sie dann
db_apis / employee.js und fügen Sie die folgende Zeile unter den Zeilen hinzu, die baseQuery deklarieren und initialisieren.
sortableColumns ist eine Whitelist mit Spalten, mit denen Kunden sortieren können. Fügen Sie dann in der Suchfunktion den folgenden if-Block hinzu, der die order by-Klausel hinzufügt. Dies muss nach dem Hinzufügen der where-Klausel, jedoch vor den Offset- und Fetch-Klauseln erfolgen.
Der erste Teil des if-Blocks prüft, ob der Client den Sortierwert übergeben hat. Wenn nicht, wird der SQL-Abfrage die Standardreihenfolge nach Klausel hinzugefügt, die in aufsteigender Reihenfolge nach Nachname sortiert wird. Wenn ein Sortierwert angegeben wird, wird dieser zuerst in Spalten- und Auftragswerte aufgeteilt, und jeder Wert wird überprüft, bevor der Abfrage eine Reihenfolge hinzugefügt wird.
Jetzt können Sie mehrere URL-Befehle ausführen, um sie zu überprüfen. Hier einige Beispiele zum Ausprobieren:
# use default sort (last_name asc) curl "http://localhost:3000/api/employees" # sort by id and use default direction (asc) curl "http://localhost:3000/api/employees?sort=id" # sort by hire_date desc curl "http://localhost:3000/api/employees?sort=hire_date:desc" # use sort with limit and skip together curl "http://localhost:3000/api/employees?limit=5&skip=5&sort=salary:desc" # should throw an error because first_name is not whitelisted curl "http://localhost:3000/api/employees?sort=first_name:desc" # should throw an error because 'other' is not a valid order curl "http://localhost:3000/api/employees?sort=last_name:other"
Die letzten beiden Beispiele sollten Ausnahmen auslösen, da sie Werte enthalten, die nicht für die Whitelist erstellt wurden. Es verwendet den Standard-Express-Fehlerhandler, sodass der Fehler als HTML-Webseite zurückgegeben wird.
FilternDie Fähigkeit, Daten zu filtern, ist eine wichtige Funktion, die alle REST-APIs bereitstellen müssen. Wie beim Sortieren kann die Implementierung einfach oder komplex sein, je nachdem, was Sie unterstützen möchten. Am einfachsten ist es, Unterstützung für Filter mit vollständiger Übereinstimmung hinzuzufügen (z. B. Nachname = Doe). Komplexere Implementierungen können Unterstützung für grundlegende Operatoren (z. B. <,>, Instr usw. usw.) und komplexe logische Operatoren (z. B. und / oder) hinzufügen, die mehrere Filter zusammenfassen können.
In diesem Beitrag werde ich versuchen, die Situation zu vereinfachen und Filterunterstützung für nur zwei Spalten hinzuzufügen: department_id und manager_id. Für jede Spalte werde ich den entsprechenden Parameter in der Abfragezeichenfolge aktivieren. Die Datenbanklogik, die die where-Klausel hinzufügt, wenn GET-Anforderungen mit einem einzelnen Mitarbeiter an den Endpunkt gesendet werden, muss aktualisiert werden, um diese neuen Filter zu berücksichtigen.
Öffnen Sie
controller / employee.js und fügen Sie die folgenden Zeilen unter der Zeile hinzu, in der der Wert req.query.sort in der Funktion get analysiert wird.
Bearbeiten
Sie dann
db_apis / employee.js , um der
Basisabfrage den Satz 1 = 1 hinzuzufügen, wie unten gezeigt.
const baseQuery = `select employee_id "id", first_name "first_name", last_name "last_name", email "email", phone_number "phone_number", hire_date "hire_date", job_id "job_id", salary "salary", commission_pct "commission_pct", manager_id "manager_id", department_id "department_id" from employees where 1 = 1`;
Natürlich ist 1 = 1 immer wahr, daher ignoriert der Optimierer es einfach. Diese Methode wird jedoch in Zukunft das Hinzufügen zusätzlicher Prädikate vereinfachen.
Ersetzen Sie in der Suchfunktion den if-Block, der beim Übergeben von context.id die where-Klausel hinzufügt, durch die folgenden Zeilen.
Wie Sie sehen können, fügt jeder if-Block einfach den an das binds-Objekt übergebenen Wert hinzu und fügt dann das entsprechende Prädikat zur where-Klausel hinzu. Speichern Sie die Änderungen und starten Sie die API neu. Verwenden Sie dann diese URL-Befehle, um dies zu überprüfen:
# filter where department_id = 90 (returns 3 employees) curl "http://localhost:3000/api/employees?department_id=90" # filter where manager_id = 100 (returns 14 employees) curl "http://localhost:3000/api/employees?manager_id=100" # filter where department_id = 90 and manager_id = 100 (returns 2 employees) curl "http://localhost:3000/api/employees?department_id=90&manager_id=100"
Das war's - die API unterstützt jetzt Paginierung, Sortierung und Filterung! Ein manueller Ansatz bietet viel Kontrolle, erfordert jedoch viel Code. Die Suchfunktion hat jetzt 58 Zeilen und unterstützt nur eingeschränkte Sortier- und Filterfunktionen. Sie können ein Modul wie den
Knex.js- Abfrage-
Generator verwenden , um diese Vorgänge zu vereinfachen.