Cloud Coffee Probe API

  • Lesedauer:13 min Lesezeit

Als nächstes kümmern wir uns um die API der Kaffeekasse, bzw starten mit der Cloud Coffee Probe API. Denn es heißt ja schließlich Cloud Kaffeekasse, also sollte auch was in die Cloud. Das erste was in die Cloud kommt ist eine API mit der der Raspberry Pi Zero W sprechen kann.

Im ersten Schritt basteln wir nur eine Probe API und schauen, ob wir eine Kommunikation zwischen Pi Zero W und API zu Stande bekommen.

Technologieauswahl

Für mich würde es sich anbieten die API mit Springboot in Java zu programmieren, da ich damit Erfahrung habe. Auch Python wäre plausibel, dann wäre das ganze Projekt in einer Sprache. Ich würde aber gerne schnell eine einfache API zum Testen aufsetzen. Ich hab schon häufiger mal gesehen, dass das ganze mit express auf Node.js schnell und einfach umzusetzen scheint. Da meine Expertise da auch recht gering ist, gibt es noch sehr viel zu lernen. Grund genug für mich die API damit anzufangen.

Der Anfang der Cloud Coffee Probe API

Zuerst erstelle ich einen Ordner api, navigiere in den Ordner und initialisiere ein node Projekt.

npm init

Anschließend installiere ich express und speichere es als Dependency.

npm i --save express

Außerdem erstelle ich noch eine Datei, die ich api.js nenne. In der Datei legen wir los die API zu erstellen. Zum Start bedienen wir uns an dem Hello World Beispiel aus der offiziellen Dokumentation. Aber eine Änderungen nehmen wir noch vor.

ES6 Modules in Node

Seit Node in Version 13 ist es möglich den Import aus ES6 zu verwenden. Mittlerweile gibt es Node in Version 14 und wir wollen ja nun wirklich nicht beim alten Kram bleiben. Also nutzen wir die ES6 Imports und Node in Version 14.

Um diese nutzen zu können müssen wir noch eine Änderung vornehmen. Wir müssen in die package.json, die npm für uns erstellt hat, etwas eintragen. Und zwar den Eintrag "type": "module". Die package.json sieht dann bei mir so aus:

{
  "name": "api",
  "version": "1.0.0",
  "description": "api for cloud coffee",
  "main": "api.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "author": "devdrik",
  "license": "ISC",
  "dependencies": {
    "express": "^4.17.1"
  },
  "type": "module"
}

Jetzt können wir anstelle von

const express = require('express');

die neue ES6 Schreibweise

import express from 'express';

verwenden. Weiter geht’s zum Hello World Beispiel.

Hello World

Das Hello World Beispiel aus der Doku mit der kleinen Änderung sieht dann so aus:

import express from 'express';
const app = express()
const port = 3000

app.get('/', (req, res) => {
  res.send('Hello World!')
})

app.listen(port, () => {
  console.log(`Example app listening at http://localhost:${port}`)
})

Wir lassen es über node api.js laufen und bekommen auf der Konsole folgendes ausgegeben:

Konsole bei Minimalbeispiel von express

Besuchen wir die Seite im Browser bekommen wir „Hello World“ angezeigt.

Hello World im Browser von express geliefert

Das war ja mal erfrischend einfach und wenig code!

Einfaches CRUD für die Cloud Coffee Probe API vorbereiten

Damit wir testen können, ob der Raspberry Pi mit der API sprechen kann, bereiten wir die CRUD Operationen vor. Dafür Erstelle ich einen dummy Array, in dem wir Werte hinzufügen, auslesen, ändern und löschen können.

Da wir mit JSON bodys arbeiten werden müssen wir der express app noch mitteilen, dass es JSON parsen soll. Dafür muss seit Version 4 nicht mehr der bodyparser verwendet werden, da er direkt in express integriert ist. Wir fügen also nur diese Zeile hinzu:

app.use(express.json())

Als nächstes erstellen wir unsere Daten. Dafür nehme ich einen einfachen Array, mit dem wir dann arbeiten können.

let dummyData = ['zero','one', 'two'];

Zuletzt erstellen wir die CRUD Operationen.

// Create
app.post('/somedata', (req, res) => {
    const data = req.body.data;
    if (data) {
        const index = dummyData.push(data);
        res.status(201).send(dummyData);
    } else {
        res.status(400).send('missing data in body');
    }
})

// Read
app.get('/somedata', (req, res) => {
    res.send(dummyData);
})

app.get('/somedata/:dataid', (req, res) => {
    const dataId = Number(req.params.dataid);
    if (dataId < dummyData.length) {
        res.status(200).send(dummyData[dataId])
    } else {
        res.status(404).send(`requested id ${dataId} not found`)
    }
})

// Update
app.put('/somedata/:dataid', (req, res) => {
    const dataId = Number(req.params.dataid);
    if(dataId < dummyData.length && dataId >= 0) {
        const data = req.body.data;
        dummyData[dataId] = data;
        res.status(200).send(dummyData);
    } else {
        res.status(404).send(`requested id ${dataId} not found`);
    }
})

// Delete
app.delete('/somedata/:dataid', (req, res) => {
    const dataId = Number(req.params.dataid);
    
    if(dataId < dummyData.length && dataId >= 0) {
        dummyData.splice(dataId, 1);
        res.status(200).send(dummyData);
    } else {
        res.status(404).send(`requested id ${dataId} not found`);
    }
})

Als Antwort schicke ich jeweils den ganzen Array zurück, dadurch sehen wir direkt, ob alles klappt. Ob das alles funktioniert probieren wir noch mit Postman aus.

Als erstes lesen wir alle Daten über einen GET Request aus. Im Header fügen wir schon mal Content-Type mit dem Wert application/json hinzu. Dadurch kann das Backend den body parsen, den wir gleich beim POST mitschicken.

Get Request an Cloud Coffee Probe API durch Postman

GET Request funktioniert schon mal, wir bekommen die initiale Liste zurück.

Danach fügen wir durch einen POST Request neue Daten hinzu. Der Body entspricht dabei dem Format, das ich in der API benötige.

POST Request an Cloud Coffee Probe API

Wieder erfolgreich, JSONs können wir also auch durch die Gegend schicken.

Auch das Ändern eines Eintrags durch einen PUT Request testen wir noch.

PUT Request an Cloud Coffee Probe API

Auch das sieht gut aus. Bleibt nur noch zu Testen, ob wir einen Eintrag löschen können. Hier geben wir den zu löschenden Index direkt als URL-Parameter mit.

DELETE Request an Cloud Coffee Probe API

Sieht alles gut aus! Alle CRUD Operationen lassen sich problemlos durchführen.

Damit ist die Dummy API auch schon fertig. Die verwenden wir im nächsten Schritt, um zu testen, ob der Pi mit der API sprechen kann.

Raspberry Pi Zero W vorbereiten

Beim Pi Zero nehmen wir wieder Python, um mit der API zu reden. Der einfachste Weg in Python Requests zu machen ist die Bibliothek requests zu verwenden. Also installieren wir die zuerst mal.

pip3 install requests

Mehr brauchen wir nicht, kann los gehen.

Test Client für die Cloud Coffee Probe API in Python

Als nächstes schreiben ein kleines Skript in Python, das mit der API kommuniziert. Es soll die vorhandenen Endpunkte testen, also get, post, put und delete auf der Route /somedata.

Wir implementieren also vier Funktionen und nutzen die requests Bibliothek. Ich definiere noch die API Url. Die API läuft auf meinem Rechner, der im gleichen WLAN hängt, wie der Pi Zero. Die Url besteht aus der IP meines Rechners, und der Route, die ich eingestellt habe.

#!/usr/bin/env python3

import requests

apiUrl = 'http://192.168.1.46:3000/somedata'


def getData():
    r = requests.get(apiUrl)
    return r.json()

def postData(newData):
    payload = {'data': newData}
    r = requests.post(apiUrl, json=payload)
    return r.json()

def updateData(id, newData):
    payload = {'data': newData}
    r = requests.put(apiUrl + '/' + str(id), json=payload)
    return r.json()

def deleteData(id):
    r=requests.delete(apiUrl + '/' + str(id))
    return r.json()

print(getData())
print(postData('Data from Pi'))
print(updateData(0, 'new at 0'))
print(deleteData(2))

Um JSON Daten zu verschicken ist der zweite Parameter im put und post request json=payload (anstelle von z. B. data=payload). Damit ist der Header content-type=application/json automatisch gesetzt und wir können JSONs verschicken.

Die Funktionen rufe ich direkt in einem print() auf, sodass mir die Antworten auf der Konsole ausgegeben werden. Das Ergebnis, wenn ich das Skript ausführe sieht dann so aus:

Antworten der Cloud Coffee Probe API auf Anfragen des Pi Zero

Wir sehen, dass zuerst der Ausgangszustand gezeigt wird. Anschließend wird ein Eintrag hinzugefügt. Dann Ändern wir den ersten Eintrag im Array und am Ende Löschen wir den Eintrag ‚two‘.

Sehr gut, der Pi Zero W kann mit der API sprechen, Ziel erreicht.

Die Grundfunktionalität ist getestet, es kann los gehen die API ordentlich aufzubauen. Es kommen ein paar Schichten hinzu (Service, Repository), ein bisschen Sicherheit braucht es auch noch. Getestet ist bislang auch noch nichts, das geht natürlich für eine vernünftige App gar nicht klar! Am Ende kommt das ganze dann in die Cloud. Der Weg dahin ist aber noch Stückchen.

Dieser Beitrag hat 3 Kommentare

  1. Patrick

    Hallo Hendrik,

    ich habe genau nach solch einer Lösung für unser Büro gesucht!

    Den Raspberry habe ich hier liegen, den Rest würde ich mir noch besorgen. Leider bin ich ein absoluter Neuling in diesem Bereich.

    Gibt es noch eine Fortsetzung? – Also ein „Endprodukt“ ?

    Gruß
    Patrick

    1. Hendrik

      Hallo Patrick,

      ein Endprodukt gibt es momentan leider noch nicht, da das Projekt einige Zeit auf Eis lag.
      Es wird aber eine Fortsetzung geben, wann genau kann ich aber noch nicht sagen.

      Viele Grüße
      Hendrik

Schreibe einen Kommentar