Lab - Simple Todo List and curl
Need a bare app for quick reference and experiments.
Preparation
- Node.js, optionally yarn
Todo App
Create a project folder and setup a dummy todo-list Express app:
mkdir todo
cd todo
yarn init -y
yarn add express
with the file app.js
const express = require('express');
const PORT = 3000;
let nextId = 4;
let todos = [
{ id: 1, title: 'Exercise', done: true, },
{ id: 2, title: 'Learn Python', done: false, },
{ id: 3, title: 'Lunch', done: false, },
];
function findTodo(id) {
return todos.find(todo => todo.id === id);
}
function addTodo({ title, done }) {
const todo = { id: nextId++, title, done };
todos.push(todo);
return todo;
}
function deleteTodo(id) {
todos = todos.filter(t => t.id !== id);
}
const app = express();
app.use(express.json());
app.set('json spaces', 2);
app.get('/', (req, res) => {
res.json({ message: 'ok' });
});
app.get('/todo', (req, res) => {
res.json(todos);
});
app.post('/todo', (req, res) => {
const { title = '', done = false } = req.body;
const todo = addTodo({ title, done });
res.json(todo);
});
app.get('/todo/:id(\\d+)', (req, res) => {
const id = parseInt(req.params.id);
const todo = findTodo(id);
if (!todo) return res.status(404).send('Not Found');
res.json(todo);
});
app.put('/todo/:id(\\d+)', (req, res) => {
const id = parseInt(req.params.id);
const { title, done } = req.body;
const todo = findTodo(id);
if (!todo) return res.status(404).send('Not Found');
if (title !== undefined) todo.title = title;
if (done !== undefined) todo.done = done;
res.json(todo);
});
app.delete('/todo/:id(\\d+)', (req, res) => {
const id = parseInt(req.params.id);
deleteTodo(id);
res.end();
});
app.get('/_bad', (req, res) => {
throw Error('This is bad');
});
app.all('*', (req, res, next) => {
res.status(400).send('Bad Request');
});
app.use((err, req, res, next) => {
res.status(500).send('Something wrong!');
});
app.listen(PORT, () => {
console.log(`Service at http://localhost:${PORT}`);
});
Then run it
$ node app.js
Service at http://localhost:3000
Using curl
Let's use curl to interact with the app:
$ curl http://localhost:3000
{"message":"ok"}
$ curl -i http://localhost:3000
HTTP/1.1 200 OK
X-Powered-By: Express
Content-Type: application/json; charset=utf-8
Content-Length: 21
ETag: W/"15-FCv+/NlfTgD7mX/4JeAWgb2wmko"
Date: Tue, 08 Oct 2024 03:37:43 GMT
Connection: keep-alive
Keep-Alive: timeout=5
{
"message": "ok"
}
For the todo list part:
$ curl http://localhost:3000/todo
[
{
"id": 1,
"title": "Exercise",
"done": true
},
{
"id": 2,
"title": "Learn Python",
"done": false
},
{
"id": 3,
"title": "Lunch",
"done": false
}
]
Now for a given item withid
2
$ curl http://localhost:3000/todo/2
{
"id": 2,
"title": "Learn Python",
"done": false
}
To see actual response:
$ curl -i localhost:3000/todo/2
HTTP/1.1 200 OK
X-Powered-By: Express
Content-Type: application/json; charset=utf-8
Content-Length: 57
ETag: W/"39-4iEWOhMKMHfAB97MzK2B0SENTfw"
Date: Mon, 07 Oct 2024 01:55:18 GMT
Connection: keep-alive
Keep-Alive: timeout=5
{
"id": 2,
"title": "Learn Python",
"done": false
}
404 and 400
But for unknown id 5:
$ curl http://localhost:3000/todo/5
Not Found
And for mis-spelled URL:
$ curl localhost:3000/todos
Bad Request
500 Error
To trigger system error:
$ curl localhost:3000/_bad
Something wrong!
POST - Create New Item
To post via curl, we have
$ curl --header "Content-Type: application/json" \
--request POST \
--data '{"title":"Dinner","done":false}' \
http://localhost:3000/todo
{
"id": 4,
"title": "Dinner",
"done": false
}
Or shorter command
curl -X POST -H "Content-Type: application/json" \
-d '{"title":"Dinner","done":false}' \
http://localhost:3000/todo
PUT - Update an Item
To update a todo item:
$ curl -X PUT -H "Content-Type: application/json" \
-d '{"done":true}' \
http://localhost:3000/todo/2
{
"id": 2,
"title": "Learn Python",
"done": true
}
DELETE - Remote an Item
$ curl -X DELETE http://localhost:3000/todo/3
$ curl http://localhost:3000/todo
[
{
"id": 1,
"title": "Exercise",
"done": true
},
{
"id": 2,
"title": "Learn Python",
"done": true
},
{
"id": 4,
"title": "Dinner",
"done": false
}
]