-
Notifications
You must be signed in to change notification settings - Fork 11
Expand file tree
/
Copy pathmain.swift
More file actions
168 lines (131 loc) · 4.39 KB
/
Copy pathmain.swift
File metadata and controls
168 lines (131 loc) · 4.39 KB
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
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
// Noze.io Simple Connect + Redis based TodoMVC implementation
// See: http://todomvc.com
// - to compile in Swift 3 invoke: swift build
// - to run result: .build/debug/todo-mvc-redis
// - access backend via:
// http://todobackend.com/client/index.html?http://localhost:1337/
// - test:
// http://todobackend.com/specs/index.html?http://localhost:1337/
import http
import console
import connect
import express
import Freddy
import redis
let app = express()
let ourAPI = "http://localhost:1337/"
// MARK: - Middleware
app.use(logger("dev"))
app.use(bodyParser.json())
app.use(cors(allowOrigin: "*"))
// MARK: - Hack Test, bug in spec tool
app.get("/*") { req, _, next in
// The /specs/index.html sends:
// Content-Type: application/json
// Accept: text/plain, */*; q=0.01
//
// The tool essentially has the misconception that the API always returns JSON
// regardless of the Accept header.
if let ctype = (req.headers[ci: "Content-Type"] as? String) {
if ctype.hasPrefix("application/json") {
req.headers[ci: "Accept"] = "application/json"
}
}
next()
}
// MARK: - Storage
// let todos = InMemoryCollectionStore<Todo>()
let todos = RedisCollectionStore<Todo>(redis.createClient())
// MARK: - Routes & Handlers
app.del("/todos/:id") { req, res, _ in
guard let id = req.params[int: "id"] else { res.sendStatus(400); return }
todos.delete(id: id) {
res.sendStatus(200)
}
}
app.del("/") { req, res, _ in
todos.deleteAll() {
res.json([]) // everything deleted, respond with an empty array
}
}
app.patch("/todos/:id") { req, res, _ in
guard let id = req.params[int: "id"] else { res.sendStatus(404); return }
guard let json = req.body.json else { res.sendStatus(400); return }
todos.get(id: id) { todo in
guard var todo = todo else { res.sendStatus(404); return }
if let t = try? json.string("title") { todo.title = t }
if let t = try? json.bool("completed") { todo.completed = t }
if let t = try? json.int("order") { todo.order = t }
todos.update(id: id, value: todo) { todo in // value type!
res.json(todo)
}
}
}
app.put("/todos/:id") { req, res, _ in
guard let id = req.params[int: "id"] else { res.sendStatus(404); return }
guard let json = req.body.json else { res.sendStatus(400); return }
todos.get(id: id) { todo in
// a title is required
guard let t = try? json.string("title") else { res.sendStatus(400); return }
let completed = try? json.bool("completed")
let order = try? json.int("order")
if var todo = todo {
todo.title = t
todo.completed = completed ?? false
todo.order = order ?? 0
todos.update(id: id, value: todo) { todo in // value type!
res.json(todo)
}
}
else { // new record under old id, respect HTTP
let newTodo = Todo(id: id, title: t,
completed: completed ?? false,
order: order ?? 0)
todos.update(id: id, value: newTodo) { todo in // value type!
res.status(201).json(todo)
}
}
}
}
app.get("/todos/:id") { req, res, _ in
guard let id = req.params[int: "id"] else { res.sendStatus(404); return }
todos.get(id: id) { todo in
guard let todo = todo else { res.sendStatus(404); return }
res.json(todo)
}
}
app.post("/*") { req, res, _ in
guard let json = req.body.json else { res.sendStatus(400); return }
guard let t = try? json.string("title") else { res.sendStatus(400); return }
let completed = try? json.bool("completed")
let order = try? json.int("order")
todos.nextKey { pkey in
let newTodo = Todo(id: pkey, title: t,
completed: completed ?? false,
order: order ?? 0)
todos.update(id: pkey, value: newTodo) { todo in // value type!
res.status(201).json(todo)
}
}
}
app.get("/*") { req, res, _ in
if req.accepts("json") != nil {
todos.getAll { todos in
res.json(todos)
}
}
else {
let clientURL = "http://todobackend.com/client/index.html?\(ourAPI)"
res.send(
"<html><body><h3>Welcome to the Noze.io Todo MVC Backend</h3>" +
"<ul>" +
"<li><a href=\"\(clientURL)\">Client</a></li>" +
"<ul>" +
"</body></html>"
)
}
}
// MARK: - Run the server
app.listen(1337) {
print("Server listening: \($0)")
}