Andreas Bruns

Softwareentwicklung für Oldenburg und Bremen

Frontend-Entwicklung mit lokalem API-Server

Viele Webanwendungen werden heutzutage als Single-Page-Webanwendung (SPA) mit Angular, React oder Vue.js umgesetzt. Man kann sie als eigenständige Anwendungen betrachten, die innerhalb des Browsers ausgeführt werden. Lediglich die fachlichen Daten müssen noch vom Server abgefragt werden, was zumeist durch REST-Aufrufe erfolgt. Bei einem Entwicklerteam aus Frontend- und Backend-Entwicklern sind die Frontendler von der REST-Schnittstelle der Backendler abhängig, was zu Verzögerungen bei der Umsetzung führen kann.

Minimale REST-Server mit kompatiblen API-Schnittstellen können bei der Frontend-Entwicklung helfen. Der auf Node basierende JSON-Server bietet passende REST-Funktionalitäten mit minimalem Konfigurationsaufwand. Das ist nicht nur für die lokale Entwicklung nützlich sondern auch unerlässlich für automatisierte Akzeptanztests (z.B. mit Selenium, Geb, Protractor).

Schnelleinstieg: Out of the box

Nach der Installation per npm erstellen wir eine JSON-Datei mit Daten und starten den JSON-Server:

npm install json-server --save-dev
echo '{"books": [ {"id":1, "title":"Angular-Buch", "pages": 320 } ] }' > db.json
json-server --watch db.json

Anschließend können wir mit curl die Bücher abfragen oder suchen, ein Buch erstellen, aktualisieren oder löschen. Beim Anlegen von Objekten ist JSON-Server so schlau, eine angegebene ID auszuwerten oder selber zu vergeben:

curl -v localhost:3000/books
curl -v localhost:3000/books/1
curl -v localhost:3000/books?title=Angular-Buch
curl -v -X POST  localhost:3000/books  -H 'content-type: application/json' -d '{ "title":"Kubernetes-Buch", "pages": 460 }'
curl -v -X PUT localhost:3000/books/2 -H 'content-type: application/json' -d '{"title":"Docker-Buch", "pages": 350 }'
curl -v -X DELETE localhost:3000/books/1

Ein Blick in die JSON-Datei zeigt, dass die Daten entsprechend aktualisiert wurden:

cat db.json

{
"books": [
{
"title": "Docker-Buch",
"pages": 350,
"id": 2
}
]

Eigener API-Server dank JSON-Server

Falls wir etwas mehr Flexibilität benötigen, lohnt sich ein eigener Server auf Basis von JSON-Server, der seinerseits auf Express beruht. Dazu legen wir lediglich eine JavaScript-Datei api-server.js an und starten sie mit: node api-server.js

const jsonServer = require('json-server');
const server = jsonServer.create();
const router = jsonServer.router('db.json');
const middlewares = jsonServer.defaults();

server.use(middlewares);

// rewrite '/api/books' to '/books'
server.use(jsonServer.rewriter({
'/api/books*': '/books'
}));

// return HTTP status specified in title parameter
server.get('/books', (req, res, next) => {
var specifiedStatus = null;
if (req.query.title) {
const numberMatchesInTitle = req.query.title.match(/\d+/);
if (numberMatchesInTitle) {
specifiedStatus = parseInt(numberMatchesInTitle[0], 10);
}
}
if (specifiedStatus) {
res.sendStatus(specifiedStatus);
} else {
next();
}
})

// transform POST request to GET request
server.use(jsonServer.bodyParser)
server.post('/legacy/books', (req, res, next) => {
const id = req.body.id;
req.url = '/books/' + id;
req.method='GET';
next();
})

server.use(router);

server.listen(3000, () => {
console.log('JSON Server is running')
});
node api-server.js

# rewrite '/api/books' to '/books'
curl -v localhost:3000/api/books

# return HTTP status specified in title parameter
curl -v localhost:3000/books?title=Docker-412

# transform POST request to GET request
curl -v -X POST localhost:3000/legacy/books -H 'content-type: application/x-www-form-urlencoded' -d 'id=2'

In der Datei haben wir ein Rewrite definiert, sodass alle „/api/books“ -Anfragen an „/books“ weitergeleitet werden.

Ein großer Vorteil eines eigenen API-Servers für die Entwicklung bietet die Erzeugung von unterschiedlichen HTTP-Status. So kann man auf einfache Weise in der Anfrage einen Status „verstecken“, mit dem der Server antworten soll und den die Webanwendung dann hoffentlich korrekt verarbeitet (z.B. „/books?title=docker414“ => HTTP-Status 414).

Außerdem wandeln wir POST-Anfragen an „/legacy/books/“ um, indem wir die ID aus dem Request-Body extrahieren und die Anfrage als GET-Anfrage mit der ID weiterverarbeiten. Das kann beispielsweise sinnvoll sein, wenn GET-Parameter zu groß sind und wir daher POST nutzen müssen. Dabei muss beim POST-Aufruf übrigens der korrekte Content-Type „application/x-www-form-urlencoded“ angegeben werden.

Was kann JSON-Server noch?

Wenn man den JSON-Server direkt im Browser aufruft (http://localhost:3000), erhält man einen Überblick zu den unterstützten Routen.

JSON-Server

JSON-Server

Die kleinen Beispiele zeigen, wie unkompliziert ein kleiner REST-Server umsetzbar ist. Einige weitere Anwendungsfälle werden direkt vom JSON-Server unterstützt:

  • Sortierung, Filterung, Paginierung und Volltextsuche
  • statische Dateien aus public-Verzeichnis ausliefern
  • JSON-Antwort programmatisch berechnen

Insbesondere bei der Umsetzung von automatisierten Akzeptanztests, bei denen die Webanwendung vollautomatisch aufgerufen und geprüft wird, komme ich ohne den JSON-Server nicht mehr aus.

Kommentare sind geschlossen.