Skip to content

Building a Simple API

You can build APIs with plain Flask routes.

Example: in-memory todo API (learning)

from flask import Flask, request
 
app = Flask(__name__)
 
todos = [
    {"id": 1, "title": "Learn Flask", "done": False},
]
 
 
@app.get("/api/todos")
def list_todos():
    return {"items": todos}
 
 
@app.post("/api/todos")
def create_todo():
    payload = request.get_json(silent=True) or {}
    title = (payload.get("title") or "").strip()
 
    if not title:
        return {"error": "validation_error", "message": "title is required"}, 400
 
    new_id = max([t["id"] for t in todos], default=0) + 1
    todo = {"id": new_id, "title": title, "done": False}
    todos.append(todo)
 
    return todo, 201
from flask import Flask, request
 
app = Flask(__name__)
 
todos = [
    {"id": 1, "title": "Learn Flask", "done": False},
]
 
 
@app.get("/api/todos")
def list_todos():
    return {"items": todos}
 
 
@app.post("/api/todos")
def create_todo():
    payload = request.get_json(silent=True) or {}
    title = (payload.get("title") or "").strip()
 
    if not title:
        return {"error": "validation_error", "message": "title is required"}, 400
 
    new_id = max([t["id"] for t in todos], default=0) + 1
    todo = {"id": new_id, "title": title, "done": False}
    todos.append(todo)
 
    return todo, 201

Notes

  • .get_json(silent=True).get_json(silent=True) avoids raising exceptions on bad JSON
  • Always validate input
  • Use status codes consistently

Moving from in-memory to database

In real apps:

  • replace the list with SQLAlchemy models
  • implement to_dict()to_dict() methods
  • add pagination and authentication

๐Ÿงช Try It Yourself

Exercise 1 โ€“ Create a Flask App

Exercise 2 โ€“ Dynamic Route

Exercise 3 โ€“ Return JSON

If this helped you, consider buying me a coffee โ˜•

Buy me a coffee

Was this page helpful?

Let us know how we did