Wisp Web Framework

repository·main·Indexed 23 days ago

https://github.com/gleam-wisp/wisp

A practical Gleam web framework designed for rapid development and easy maintenance. Wisp focuses on simplicity through two core abstractions: handlers, which process HTTP requests and return responses, and middleware, which intercept and augment the request/response lifecycle. It provides adapters for servers such as Mist (wisp_mist) and Ewe (wisp_ewe), and includes utilities for routing, JSON handling, cookie management, and serving static assets.

Tokens
2.7K
Snippets
17
Records
28
Agent score
81%

What's inside Wisp

  1. List of Wisp examples

    main

    The following modules contain standalone examples demonstrating various Wisp capabilities. You can find the source code in ./src/$MODULE_NAME and tests in ./test/$MODULE_NAME.

    • hello_world - Hello, World!
    • routing - Routing
    • working_with_form_data - Working with form data
    • working_with_json - Working with JSON
    • working_with_other_formats - Working with other formats
    • using_a_database - Using a database
    • serving_static_assets - Serving static assets
    • logging - Logging
    • working_with_cookies - Working with cookies
    • working_with_files - Working with files
  2. What is Middleware in Wisp

    main

    Middleware allows you to intercept and augment the request/response lifecycle. A middleware is a function that takes a response-returning function as its final argument and returns a Response.

    Middleware can be applied to handlers using Gleam's use syntax. This allows you to layer functionality like logging, authentication, or serving static files on top of your main request handling logic.

    import wisp.{type Request, type Response}
    
    pub fn handle_request(request: Request) -> Response {
      use <- wisp.log_request(request)
      use <- wisp.serve_static(request, under: "/static", from: "/public")
      wisp.ok()
    }
  3. Understand the Wisp application structure

    main

    A standard Wisp application is typically organized into three main layers:

    1. Entrypoint Module (app): Responsible for initialization and starting the web server.
    2. Web Module (app/web): Contains the middleware stack, custom types, and helper functions used by request handlers.
    3. Router Module (app/router): Contains the request handlers (or 'router') that define how specific requests are processed.
  4. What are Handlers in Wisp

    main

    A handler is the core logic of your application. It is a function that accepts an HTTP Request and returns an HTTP Response.

    To make handlers more powerful, you can pass additional arguments, such as a custom Context type. This context is typically used to hold application state like database connections, configuration, or user sessions.

    import wisp.{type Request, type Response}
    
    pub type Context {
      Context(secret: String)
    }
    
    pub fn handle_request(request: Request, context: Context) -> Response {
      wisp.ok()
    }
  5. Use a Context type to provide database connections to handlers

    main

    In Wisp applications that require external resources like database connections, the recommended pattern is to define a Context type. This type holds the connection or client and is passed through the application layers.

    1. Define the Context: Create a record type (e.g., Context) that includes your database connection.
    2. Initialize in Main: In your main function, establish the database connection and wrap it in your Context record.
    3. Pass to Handlers: Pass the Context record into your top-level handler function so that individual request handlers can access the database.
  6. Route requests using pattern matching in `handle_request`

    main
    In Wisp, routing is typically implemented by pattern matching on the Request object within your main handle_request function. You can inspect the request path and the HTTP method to determine which specific handler function should process the request.