USE CASE

?? Build a REST API

Create a JSON API server using the Backend stack

What You'll Build

A simple REST API with endpoints for managing a to-do list:

Prerequisites

Make sure you have Ifá-Lang installed with the Backend stack:

ifa --version
# Ifá-Lang v1.2.2 (Backend stack enabled)

1 Create the Project

oja new todo-api
cd todo-api

2 Define the Server

?? src/main.ifa
// Todo API Server
ayanmo Backend = import("@stacks/backend");

// In-memory storage
ayanmo todos = [];
ayanmo next_id = 1;

// Create router
ayanmo router = Backend.router();

// GET /todos - List all
router.get("/todos", (req, res) => {
    res.json(todos);
});

// POST /todos - Create new
router.post("/todos", (req, res) => {
    ayanmo body = req.json();
    ayanmo todo = {
        "id": next_id,
        "title": body["title"],
        "done": iro
    };
    ayanmo next_id = next_id + 1;
    ayanmo todos = Ogunda.push(todos, todo);
    res.status(201).json(todo);
});

// GET /todos/:id - Get one
router.get("/todos/:id", (req, res) => {
    ayanmo id = Ogbe.parse_int(req.params["id"]);
    ayanmo found = nil;
    
    fun todo ninu todos {
        ti (todo["id"] == id) {
            ayanmo found = todo;
        }
    }
    
    ti (found != nil) {
        res.json(found);
    } bib?k? {
        res.status(404).json({"error": "Not found"});
    }
});

// DELETE /todos/:id - Delete one
router.delete("/todos/:id", (req, res) => {
    ayanmo id = Ogbe.parse_int(req.params["id"]);
    ayanmo new_todos = [];
    
    fun todo ninu todos {
        ti (todo["id"] != id) {
            ayanmo new_todos = Ogunda.push(new_todos, todo);
        }
    }
    
    ayanmo todos = new_todos;
    res.status(204).send("");
});

// Start server
Irosu.fo("?? Starting Todo API on port 8080...");
Backend.serve(router, 8080);

3 Run the Server

ifa run src/main.ifa

Output:

?? Starting Todo API on port 8080...

4 Test the API

In another terminal:

# Create a todo
curl -X POST http://localhost:8080/todos \
  -H "Content-Type: application/json" \
  -d '{"title": "Learn Ifá-Lang"}'

# Response: {"id": 1, "title": "Learn Ifá-Lang", "done": false}

# List todos
curl http://localhost:8080/todos

# Response: [{"id": 1, "title": "Learn Ifá-Lang", "done": false}]

# Get one todo
curl http://localhost:8080/todos/1

# Delete a todo
curl -X DELETE http://localhost:8080/todos/1

Adding Middleware

Add logging and CORS support:

// Logging middleware
router.use((req, res, next) => {
    Irosu.fo(req.method + " " + req.path);
    next();
});

// CORS middleware
router.use((req, res, next) => {
    res.header("Access-Control-Allow-Origin", "*");
    res.header("Access-Control-Allow-Methods", "GET, POST, DELETE");
    next();
});

Adding Persistence

Save todos to a file using Odi:

// Load todos on startup
ti (Odi.exists("todos.json")) {
    ayanmo data = Odi.read("todos.json");
    ayanmo todos = Ogbe.parse_json(data);
}

// Save function
ise save_todos() {
    ayanmo json = Ogbe.format_json(todos);
    Odi.write("todos.json", json);
}

// Call save after changes
router.post("/todos", (req, res) => {
    // ... create todo ...
    save_todos();
    res.status(201).json(todo);
});

?? What You Learned: