Gebweb notes (auto-discovery, HTTP + self-signed HTTPS)

A minimal JSON CRUD API using auto-discovery: a `@Service` is

Path
gebweb/examples/notes.gb
Category
General

autowired into a @Controller and gebweb.app() is called with NO

controller list, so the framework finds and mounts the controller.

In-memory, no database. Listens on two ports at once - plain HTTP (8080)

and self-signed HTTPS (8443) - with two gebweb.listen calls + http.wait.

Run:

geblang examples/notes.gb

Then (HTTP, or HTTPS with -k for the self-signed certificate):

curl 127.0.0.1:8080/notes -d '{"text":"buy milk"}'

curl -k https://127.0.0.1:8443/notes

curl 127.0.0.1:8080/notes/nope # 404 problem-details JSON

Docs: http://127.0.0.1:8080/docs (SwaggerUI).

Source

import gebweb;
import http;
import io;

@Service
class NoteService {
    dict<string, dict<string, any>> notes;
    int counter;

    func NoteService() {
        this.notes = {};
        this.counter = 0;
    }

    func add(string text): dict<string, any> {
        this.counter = this.counter + 1;
        let note = {"id": "n-${this.counter}", "text": text};
        this.notes[note["id"] as string] = note;
        return note;
    }

    func all(): list<dict<string, any>> {
        let out = [];
        for (id in this.notes.keys()) {
            out = out.push(this.notes[id]);
        }
        return out;
    }

    func find(string id): ?dict<string, any> {
        if (this.notes.contains(id)) {
            return this.notes[id];
        }
        return null;
    }
}

class NoteInput {
    string text;
}

@Controller("/notes")
class NotesController extends gebweb.Controller {
    NoteService notes;

    func NotesController(NoteService notes) {
        this.notes = notes;
    }

    @Get("")
    @Summary("List notes")
    func index(): http.Response {
        return this.json(this.notes.all());
    }

    @Post("")
    @Summary("Create a note")
    func create(NoteInput body): http.Response {
        return this.json(this.notes.add(body.text), 201);
    }

    @Get("/{id}")
    @Summary("Fetch one note")
    func show(string id): http.Response {
        let note = this.notes.find(id);
        if (note == null) {
            throw gebweb.notFound("no note " + id);
        }
        return this.json(note);
    }
}

let app = gebweb.app();
gebweb.listen(app, "127.0.0.1:8080");
let server = gebweb.listen(app, "127.0.0.1:8443", {"tls": {"selfSigned": true}});
io.println("Notes API: http://127.0.0.1:8080 and https://127.0.0.1:8443 (self-signed) - try /notes, /docs");
http.wait(server);