karlseguin / http.zig

An HTTP/1.1 server for zig
MIT License
454 stars 31 forks source link

Issues with the API for creating routes #32

Closed ThePuzzledDev closed 6 months ago

ThePuzzledDev commented 6 months ago

I've only done some minimal investigation, so I may be wrong, but I can't seem to find a way to have data that persists throughout the whole server instance.

pub fn main() !void {
    // ...
    var data = someDynamicallyChangingData();    

    // How can I pass data to the `getUser` function?
    var router = server.router();
    router.get("/api/user/:id", getUser);

    // ...
}

Currently I could only do something like this

pub fn main() !void {
    // ... 

    var router = server.router();
    router.get("/api/user/:id", getUser);

    // ...
}

fn getUser(req: *httpz.Request, res: *httpz.Response) !void {
    var data = someDynamicallyChangingData();   

    try res.json(.{.id = req.param("id").?, .name = "Teg", .tag = data}, .{});
}

Perhaps something like this?

pub fn main() !void {
    // ... 

     var data = someDynamicallyChangingData(); 

    var router = server.router();
    router.get("/api/user/:id", getUser);

    if (router.get("/api/user/:id")) |route| {
        try route.res.json(.{.id = route.req.param("id").?, .name = "Teg", .tag = data}, .{});
    }

    // ...
}

Appologies is I am missing something or was unclear. I just very quickly glanced through the library, and could not find a way to do this. Just wondering if there was a way to do what I'm asking for.

zigster64 commented 6 months ago

If I read that right - I think you want that someDynamicallyChangingData to be your "global but ever changing state", and you want that to be accessible from inside the handler ?

(I can't see the code where you are creating the server, so Im only guessing intent here)

If so, then have a look at using ServerCtx() instead of server. as per https://github.com/zigster64/http.zig#complex-use-case-1---shared-global-data

Then your handler function would get an extra param, being a reference to that global data

fn getUser(data: *SomeDynamicStateInfo, req: *httpz.Request, res: *httpz.Response) !void {
    try res.json(.{.id = req.param("id").?, .name = "Teg", .tag = data}, .{});
}

Apologies if that doesn't address the question, but I think that might get you on the right track ?

ThePuzzledDev commented 6 months ago

Yes that's exactly what I'm looking for. Thanks