1/floscodes/zerve v0.62

Simple web framework for zig


zerve

A simple framework for writing web services in zig.

Create a simple web app

const zrv = @import("zerve"); // Or set the path to zerve.zig e.g. @import("zerve-main/src/zerve.zig");
const Request = zrv.Request;
const Response = zrv.Response;
const Server = zrv.Server;
const Route = zrv.Route;
const allocator = std.heap.page_allocator; // Choose any allocator you want!

fn index(req: *Request) Response {
    _=req;
    return Response.write("hello!");
}

fn about(req: *Request) Response {
    _=req;
    return Response.write("about site");
}

fn writeJson(req: *Request) Response {
    _=req;
    return Response.json("[1, 2, 3, 4]");
}

pub fn main() !void {
     const rt = [_]Route{.{"/", index}, .{"/about", about}, .{"/json", writeJson}};

     try Server.listen("0.0.0.0", 8080, &rt, allocator); // listens to http://localhost:8080
                                                         // http://localhost:8080/  "hello!"
                                                         // http://localhost:8080/about "about site"
                                                         // http://localhost:8080/json  "[1, 2, 3, 4]" (JSON-Response)
}

Types

Route

To write a web service with zerve you have to configure one or more Routes. They are being set by creating an Array of Route.

Example:

const rt = [_]Route{.{"/hello", helloFunction}, "/about", aboutFunction};

You can also set only one path and link it to a handler function, but since Server.listen() takes an Array of Route as one of it's arguments, you have do declare it as an Array as well:

const rt = [_]Route{.{"/hello", helloFunction}};

Handler Functions

Every Request is handled by a handler function. It has to be of this type: fn(req: *Request) Response

Example:

fn hello(req: *Request) Response {
    _ = req;
    return Response.write("hello"); // `Server` will return a Reponse with body "hello". You will see "hello" on your browser.
}

Request

This represents the Request sent by the client.

pub const Request = struct {
    /// The Request Method, e.g. "GET"
    method: Method,
    /// HTTP-Version of the Request sent by the client
    httpVersion: HTTP_Version,
    /// Represents the request headers sent by the client
    headers: []const Header,
    /// The Request URI
    uri: []const u8,
    /// Represents the request body sent by the client
    body: []const u8,
};

Get Query Params

zerve lets you easily extract query params no matter if Requestmethod is GETor POST.

This can be done by using the getQuery method of Request.

Example:

fn index(req: Request) Response {

    // Assuming that a query string has been sent by the client containing the requested param,
    // e.g. `?user=james`

    const user = req.getQuery("user"); // This will return an optional
    
    if (user == null) return Response.write("") else return Response.write(user.?);
    
}

Get value of Request header by key

You can get the header value of any sent header by the client with the headermethod of Request.

Example:

fn index(req: *Request) Response {
    
    // Get value of the 'Content-Type' header

    const h = req.header("Content-Type"); // This will return an optional

    if (h == null) return Response.write("Header not found!") else return Response.write(h.?);

}

Response

A Response that is sent ny the server. Every handler function has to return a Response.

pub const Response = struct {
    httpVersion: HTTP_Version = HTTP_Version.HTTP1_1,
    /// Response status, default is "200 OK"
    status: stat.Status = stat.Status.OK,
    /// Response eaders sent by the server
    headers: []const Header = &[_]Header{.{ .key = "Content-Type", .value = "text/html; charset=utf-8" }},
    /// Response body sent by the server
    body: []const u8 = "",

    /// Write a simple response.
    pub fn write(s: []const u8) Response

    /// Send a response with json content.
    pub fn json(j: []const u8) Response

    /// Send a response with status not found.
    pub fn notfound(s: []const u8) Response

    /// Send a response with status forbidden.
    pub fn forbidden(s: []u8) Response
};

Header

Every Request or Response has Headers represented by an Array of Headers. Every Header has a key and a value.

pub const Header = struct {
    key: []const u8,
    value: []const u8,
};

Cookies

Read Cookie from Request

To read the Cookie of a request by key, Request has a cookie-method. It returns an optional and fetches the value of a Request.Cookie.

Get Request Cookie value by key:

fn index(req: *Request) Response {
    
    // Fetches the cookie value by cookie name.
    // The `cookie` method will return an optional and will be `null`
    // in case that the cookie does not exist.

    const cookie = if (req.cookie("password")) |password| password else "";

    return Response.write("cookie-test");
}

Add Cookie to Response

To send a cookie in your Response just add a Response.Cookie to the cookies field. The cookies field is a slice of Response.Cookie.

fn index(_: *Request) Response {

    // Define a cookie with name and value.
    // It will live for 24 hours, since `maxAge` represents
    // lifetime in seconds.
    // See all field of the `Response.Cookie` struct below.

    const cookie = Response.Cookie{.name="User", .value="James", .maxAge=60*60*24};

    var res = Response.write("Set Cookie!");
    // add cookie to the `cookies` field which is a slice of `Response.Cookie`
    res.cookies = &[_]Response.Cookie{.{cookie}};
    
    return res;
}

This are the fields of Response.Cookie:

    name: []const u8,
    value: []const u8,
    path: []const u8 = "/",
    domain: []const u8 = "",
    /// Indicates the number of seconds until the cookie expires.
    maxAge: i64 = 0,
    secure: bool = true,
    httpOnly: bool = true,
    sameSite: SameSite = .lax,

Method

Represents the http method of a Request or a Response.

pub const Method = enum {
    GET,
    POST,
    PUT,
    HEAD,
    DELETE,
    CONNECT,
    OPTIONS,
    TRACE,
    PATCH,
    UNKNOWN,

    /// Turns the HTTP_method into a u8-Slice.
    pub fn stringify(m: Method) []const u8 {...}
};

HTTP-Version

The HTTP-Version of a Request or a Response.

pub const HTTP_Version = enum {
    HTTP1_1,
    HTTP2,

    /// Parses from `[]u8`
    pub fn parse(s: []const u8) HTTP_Version {...}

    /// Stringifies `HTTP_Version`
    pub fn stringify(version: HTTP_Version) []const u8 {...}

};

Namespaces

Server

Server is a namespace to configure IP and Port the app will listen to by calling Server.listen(), as well as the routing paths ([]Route) it shall handle. You can also choose an allocator that the app will use for dynamic memory allocation.

pub fn listen(ip: []const u8, port: u16, rt: []const Route, allocator: std.mem.Allocator) !void {...}

Package Contents

  • gyro.zzz
  • LICENSE
  • build.zig
  • src/res_cookie.zig
  • src/server.zig
  • src/req_cookie.zig
  • src/zerve.zig
  • src/status.zig
  • src/types.zig
  • README.md
  • zig.mod
  • build.zig.zon
  • .gitignore

History

Published On Tree @ Commit Size
v0.62 Wed, 12 Jun 2024 04:47:08 UTC Tree 39.699 KB
v0.61 Fri, 26 May 2023 11:00:46 UTC Tree 39.541 KB
v0.60 Sat, 20 May 2023 15:42:17 UTC Tree 39.896 KB
v0.59 Sat, 20 May 2023 15:41:55 UTC Tree 39.896 KB
v0.58 Sat, 20 May 2023 15:39:53 UTC Tree 39.775 KB
v0.57 Sat, 20 May 2023 15:39:03 UTC Tree 39.774 KB
v0.56 Sat, 20 May 2023 15:26:07 UTC Tree 39.332 KB
v0.55 Sat, 20 May 2023 15:25:16 UTC Tree 39.332 KB
v0.54 Fri, 19 May 2023 12:45:54 UTC Tree 39.326 KB
v0.53 Fri, 19 May 2023 12:35:01 UTC Tree 38.606 KB
v0.52 Fri, 19 May 2023 11:34:03 UTC Tree 38.316 KB
v0.51 Fri, 19 May 2023 10:49:24 UTC Tree 36.306 KB
v0.50 Fri, 19 May 2023 10:36:36 UTC Tree 35.843 KB
v0.49 Fri, 19 May 2023 10:33:25 UTC Tree 35.837 KB
v0.48 Fri, 19 May 2023 09:39:05 UTC Tree 34.271 KB
v0.47 Thu, 18 May 2023 18:47:14 UTC Tree 33.731 KB
v0.46 Thu, 18 May 2023 18:44:28 UTC Tree 33.700 KB
v0.45 Thu, 18 May 2023 14:55:32 UTC Tree 33.470 KB
v0.44 Thu, 18 May 2023 10:14:25 UTC Tree 33.362 KB
v0.43 Wed, 17 May 2023 22:37:56 UTC Tree 32.577 KB
v0.42 Wed, 17 May 2023 21:40:48 UTC Tree 31.896 KB
v0.41 Wed, 17 May 2023 21:33:29 UTC Tree 31.752 KB
v0.40 Wed, 17 May 2023 21:20:42 UTC Tree 31.291 KB
v0.39 Wed, 17 May 2023 19:38:53 UTC Tree 31.546 KB
v0.38 Wed, 17 May 2023 19:29:22 UTC Tree 31.442 KB
v0.37 Wed, 17 May 2023 16:03:29 UTC Tree 30.750 KB
v0.36 Tue, 16 May 2023 10:11:56 UTC Tree 30.451 KB
v0.35 Tue, 16 May 2023 09:13:06 UTC Tree 30.138 KB
v0.34 Mon, 15 May 2023 15:33:57 UTC Tree 30.065 KB
v0.33 Sat, 13 May 2023 08:38:35 UTC Tree 27.942 KB
v0.32 Wed, 10 May 2023 19:21:45 UTC Tree 27.900 KB
v0.31 Thu, 04 May 2023 12:03:51 UTC Tree 26.100 KB
v0.30 Thu, 04 May 2023 12:02:43 UTC Tree 26.093 KB
v0.29 Thu, 04 May 2023 09:11:38 UTC Tree 26.202 KB
v0.28 Thu, 04 May 2023 09:08:52 UTC Tree 25.962 KB
v0.27 Thu, 04 May 2023 09:07:35 UTC Tree 25.921 KB
v0.26 Wed, 03 May 2023 18:49:59 UTC Tree 25.867 KB
v0.25 Tue, 02 May 2023 20:24:56 UTC Tree 25.879 KB
v0.24 Tue, 02 May 2023 20:23:19 UTC Tree 25.879 KB
v0.23 Tue, 02 May 2023 19:48:24 UTC Tree 25.700 KB
v0.22 Mon, 01 May 2023 08:10:22 UTC Tree 25.711 KB
v0.21 Sun, 30 Apr 2023 10:48:09 UTC Tree 25.705 KB
v0.20 Sun, 30 Apr 2023 10:28:30 UTC Tree 25.661 KB
v0.19 Sat, 29 Apr 2023 10:59:33 UTC Tree 25.663 KB
v0.18 Sat, 29 Apr 2023 10:46:48 UTC Tree 25.725 KB
v0.17 Fri, 28 Apr 2023 20:26:32 UTC Tree 25.367 KB
v0.16 Fri, 28 Apr 2023 19:53:59 UTC Tree 25.084 KB
v0.15 Tue, 25 Apr 2023 21:21:54 UTC Tree 25.209 KB
v0.14 Tue, 25 Apr 2023 09:40:21 UTC Tree 25.136 KB
v0.13 Tue, 25 Apr 2023 09:37:29 UTC Tree 25.148 KB
v0.12 Tue, 25 Apr 2023 09:36:22 UTC Tree 25.146 KB
v0.11 Tue, 25 Apr 2023 09:06:25 UTC Tree 25.057 KB
v0.10 Mon, 24 Apr 2023 20:21:49 UTC Tree 25.129 KB
v0.9 Mon, 24 Apr 2023 15:08:38 UTC Tree 25.146 KB
v0.8 Mon, 24 Apr 2023 15:07:50 UTC Tree 25.475 KB
v0.7 Mon, 24 Apr 2023 15:01:38 UTC Tree 21.152 KB
v0.6 Mon, 24 Apr 2023 12:48:41 UTC Tree 21.088 KB
v0.5 Mon, 24 Apr 2023 12:45:00 UTC Tree 20.968 KB
v0.4 Mon, 24 Apr 2023 12:21:14 UTC Tree 20.942 KB
v0.3 Mon, 24 Apr 2023 12:13:50 UTC Tree 20.599 KB
v0.2 Mon, 24 Apr 2023 12:04:28 UTC Tree 20.512 KB
v0.1 Mon, 24 Apr 2023 10:26:04 UTC Tree 19.955 KB