3 · Tu primera API JSON

Convirtamos el servidor en una API JSON para notas: listarlas, crear una, traer una por id. Un handler es una función de Request a Response — lees campos del request, devuelves una respuesta.

Todo junto

Reemplaza src/main.nx:

import "std/web"
import "nyx-serve/src/server"

var g_notes: Map = Map.new()
var g_next_id: int = 1

fn list_notes(req: Request) -> Response {
    var sb: StringBuilder = StringBuilder.new()
    sb.append("[")
    let keys: Array = g_notes.keys()
    var i: int = 0
    while i < keys.length() {
        let k: String = keys[i]
        let title: String = g_notes.get(k)
        if i > 0 { sb.append(",") }
        sb.append("{\"id\":" + k + ",\"title\":\"" + title + "\"}")
        i = i + 1
    }
    sb.append("]")
    return response_json(200, sb.to_string())
}

fn create_note(req: Request) -> Response {
    if not req.form.contains("title") {
        return response_json(400, "{\"error\":\"title is required\"}")
    }
    let title: String = req.form.get("title")
    let id: String = int_to_string(g_next_id)
    g_notes.insert(id, title)
    g_next_id = g_next_id + 1
    return response_json(201, "{\"id\":" + id + "}")
}

fn get_note(req: Request) -> Response {
    let id: String = req.params.get("id")
    if not g_notes.contains(id) {
        return response_json(404, "{\"error\":\"not found\"}")
    }
    let title: String = g_notes.get(id)
    return response_json(200, "{\"id\":" + id + ",\"title\":\"" + title + "\"}")
}

fn main() {
    g_notes = Map.new()
    let app: App = app_new()
    app_get(app, "/notes", list_notes)
    app_post(app, "/notes", create_note)
    app_get(app, "/notes/{id}", get_note)
    serve_app(app, 3000, 8)
}

Tres cosas que vale nombrar:

Pruébalo

$ nyx run
notes-app starting on port 3000 with 8 workers
$ curl -X POST -d "title=buy coffee" localhost:3000/notes
{"id":1}
$ curl -X POST -d "title=write docs" localhost:3000/notes
{"id":2}
$ curl localhost:3000/notes
[{"id":2,"title":"write docs"},{"id":1,"title":"buy coffee"}]
$ curl localhost:3000/notes/1
{"id":1,"title":"buy coffee"}
$ curl localhost:3000/notes/99
{"error":"not found"}
El almacén es un Map global, así que las notas desaparecen al reiniciar. El paso 7 lo cambia por nyx-kv — una base de datos real — sin cambiar la forma de los handlers.