1 | // HTTP Modul einbinden |
---|
2 | var http = require('http'); |
---|
3 | |
---|
4 | //FileSystem Modul einbinden |
---|
5 | var fs = require('fs'); |
---|
6 | |
---|
7 | // Express einbinden |
---|
8 | var express = require('express'); |
---|
9 | // Express-App erzeugen und konfigurieren |
---|
10 | var app = express(); |
---|
11 | |
---|
12 | // Body-Parser für Requests einbinden |
---|
13 | var bodyParser = require('body-parser'); |
---|
14 | // Parsen von Querystrings (application/x-www-form-urlencoded) aktivieren |
---|
15 | app.use(bodyParser.urlencoded({ extended: true })); |
---|
16 | // Parsen von JSON (application/json) aktivieren |
---|
17 | app.use(bodyParser.json()); |
---|
18 | |
---|
19 | // statischen Fileserver für das Verzeichnis /app einrichten |
---|
20 | // __dirname ist das Verzeichnis des aktuell laufenden Skripts |
---|
21 | app.use(express.static(__dirname + '/app')); |
---|
22 | |
---|
23 | // CORS erlauben |
---|
24 | app.use(function (req, res, next) { |
---|
25 | // Website, die sich verbinden darf: Angular WDS -- alternativ: '*' für alle Quellen |
---|
26 | res.setHeader('Access-Control-Allow-Origin', 'http://localhost:4200'); |
---|
27 | // Angabe der erlaubten HTTP Methoden |
---|
28 | res.header('Access-Control-Allow-Methods', 'GET,PUT,POST,DELETE'); |
---|
29 | // Angabe der erlaubten request Header |
---|
30 | res.header('Access-Control-Allow-Headers', 'Content-Type'); |
---|
31 | // Request zur nächsten Schicht der Middleware weiterleiten |
---|
32 | next(); |
---|
33 | }); |
---|
34 | |
---|
35 | // HTTP Server erzeugen |
---|
36 | var server = http.createServer(app); |
---|
37 | |
---|
38 | // Port aus der Umgebung des HostLabs holen. |
---|
39 | //const port = process.env.PORT; |
---|
40 | const port = 3000; |
---|
41 | // Server an Port binden |
---|
42 | server.listen(port); |
---|
43 | |
---|
44 | // Artikel im Shop |
---|
45 | var articles = []; |
---|
46 | |
---|
47 | // Einlesen aus Datei (falls vorhanden) |
---|
48 | // Auf diese Weise lässt sich sehr einfach eine serverseitige Datenhaltung |
---|
49 | // für sehr kleine Projekte implementieren. |
---|
50 | // __dirname ist das Verzeichnis des aktuell laufenden Skripts |
---|
51 | var filename = __dirname + '/articles.json'; |
---|
52 | |
---|
53 | try { |
---|
54 | var filedata = fs.readFileSync(filename); |
---|
55 | articles = JSON.parse(filedata); |
---|
56 | console.log(articles.length + ' Datensätze gelesen'); |
---|
57 | console.log(articles); |
---|
58 | } catch (err) { |
---|
59 | // Keine Datei vorhanden, nichts tun |
---|
60 | console.log('Keine Datensätze gelesen'); |
---|
61 | } |
---|
62 | |
---|
63 | // ID für neue Objekte |
---|
64 | var nextID = getMaxId() + 1; |
---|
65 | |
---|
66 | // GET-Request: Alle Artikel ausliefern |
---|
67 | app.get('/articles', function(req, res) { |
---|
68 | logUrl(req); |
---|
69 | |
---|
70 | res.contentType('application/json'); |
---|
71 | res.status(200).send(JSON.stringify(articles)); |
---|
72 | }); |
---|
73 | |
---|
74 | // GET-Request: Einen Artikel mit ID ausliefern |
---|
75 | // id wird zum Attribut des Objektes req.params |
---|
76 | app.get('/articles/:id', function(req, res) { |
---|
77 | logUrl(req); |
---|
78 | |
---|
79 | // Artikel finden |
---|
80 | var index = findIndexById(req.params.id); |
---|
81 | var status = 200; |
---|
82 | var message = ''; |
---|
83 | var contentType = 'application/json'; |
---|
84 | |
---|
85 | if (index != -1) { |
---|
86 | message = articles[index]; |
---|
87 | } else { |
---|
88 | // Artikel nicht gefunden |
---|
89 | status = 404; |
---|
90 | contentType = 'text/plain'; |
---|
91 | message = 'Artikel ' + req.params.id + ' nicht gefunden.'; |
---|
92 | } |
---|
93 | |
---|
94 | res.contentType(contentType); |
---|
95 | res.status(status).send(JSON.stringify(message)); |
---|
96 | }); |
---|
97 | |
---|
98 | // POST-Request: Neuen Artikel anlegen |
---|
99 | app.post('/articles', function(req, res){ |
---|
100 | logUrl(req); |
---|
101 | console.log(req.body); |
---|
102 | |
---|
103 | // req.body ist ein Objekt mit den Formulardaten |
---|
104 | // ID einfügen |
---|
105 | // Achtung: Unter Umständen kann es gefährlich sein, das body-Objekt strukturell zu verändern. |
---|
106 | // Insbesondere können so später unerwartete Seiteneffekte entstehen. |
---|
107 | // Dann empfiehlt es sich, zuvor eine Kopie anzulegen und diese zu verändern. |
---|
108 | // In diesem Beispiel ist das unkritisch, da das Attribut id bereits vom Client |
---|
109 | // mitgeschickt wurde (Wert -1) |
---|
110 | req.body.id = nextID; |
---|
111 | nextID++; |
---|
112 | articles.push(req.body); |
---|
113 | updateFile(); |
---|
114 | |
---|
115 | res.contentType('application/json'); |
---|
116 | res.status(201).send(JSON.stringify(req.body)); |
---|
117 | }); |
---|
118 | |
---|
119 | // PUT-Request: Artikel editieren |
---|
120 | app.put('/articles/:id', function(req, res){ |
---|
121 | logUrl(req); |
---|
122 | console.log(req.body); |
---|
123 | |
---|
124 | // id finden |
---|
125 | var index = findIndexById(req.params.id); |
---|
126 | // req.body ist ein Objekt mit den Formulardaten |
---|
127 | articles[index] = req.body; |
---|
128 | updateFile(); |
---|
129 | |
---|
130 | res.contentType('application/json'); |
---|
131 | res.status(200).send(JSON.stringify(req.body)); |
---|
132 | }); |
---|
133 | |
---|
134 | // DELETE-Request: Artikel löschen |
---|
135 | app.delete('/articles/:id', function(req, res){ |
---|
136 | logUrl(req); |
---|
137 | |
---|
138 | // Element finden |
---|
139 | var index = findIndexById(req.params.id); |
---|
140 | // Element löschen |
---|
141 | articles.splice(index, 1); |
---|
142 | updateFile(); |
---|
143 | |
---|
144 | console.log(articles); |
---|
145 | |
---|
146 | res.contentType('text/plain'); |
---|
147 | res.status(200).send('Artikel ' + req.params.id + ' gelöscht'); |
---|
148 | }); |
---|
149 | |
---|
150 | |
---|
151 | /** |
---|
152 | * Findet bestimmten Artikel anhand ID |
---|
153 | */ |
---|
154 | function findIndexById(id) { |
---|
155 | for (var i = 0; i < articles.length; i++) { |
---|
156 | if (articles[i].id == id) { |
---|
157 | return i; |
---|
158 | } |
---|
159 | } |
---|
160 | return -1; |
---|
161 | } |
---|
162 | |
---|
163 | /** |
---|
164 | * Sucht die größte ID im Array |
---|
165 | */ |
---|
166 | function getMaxId() { |
---|
167 | var max = 0; |
---|
168 | |
---|
169 | for (var a of articles) { |
---|
170 | if (a.id > max) { |
---|
171 | max = a.id; |
---|
172 | } |
---|
173 | } |
---|
174 | return parseInt(max); |
---|
175 | } |
---|
176 | |
---|
177 | /** |
---|
178 | * Schreibt den aktuellen Zustand des Arrays in die Datei |
---|
179 | * @returns |
---|
180 | */ |
---|
181 | function updateFile() { |
---|
182 | fs.writeFileSync(filename, JSON.stringify(articles)); |
---|
183 | } |
---|
184 | |
---|
185 | /** |
---|
186 | * Gibt HTTP-Methode und Zieladresse auf der Konsole aus |
---|
187 | */ |
---|
188 | function logUrl(req) { |
---|
189 | console.log(req.method + ' ' + req.url); |
---|
190 | } |
---|