Response

Responses is mostly an Azu implementation detail to enable more type-safe definitions.

Response is mostly an Azu implementation detail to enable more type-safe definitions, and it does not represent the raw response from the HTTP::Server::Response. Instead responses are plain simple crystal objects that allows for easy implementation, validation and test-ability.

Azu::Responses main job is to render the body of the responses to be sent back to browsers and API clients.

Defining an Azu::Response

Responses are created by including the Azu::Response and defining a render method that contains the body for the HTTP response.

# Response Docs https://azutopia.gitbook.io/azu/endpoints/response
module MyApp
  class UserResponse
    include Response

    def initialize(@name : String)end

    def render
      "Hello, #{@name}!"
    end
  end
end

Because of the simplicity of the module it is easy to create type safe responses, that can be validated and easily tested.

For example, lets say we want to render an IndexPage for a dashboard, we want to make ensure that a title is always provided in order to display the page.

module MyApp
  class Dashboard::IndexPage
    include Response
    
    def initialize(@title : String)
    end

    def render
      "<h1>#{@title}</h1>"
    end
  end
end

Responses are simple Crystal classes that includes the Azu::Response module, there is no magic or macro needed, simply follows crystal conventions.

Rendering Inline HTML

Azu provides a Markup module to allow you write HTML in plain crystal

Taking the example IndexPage above we can represent the H1 using Markup DSL

module MyApp
  class Dashboard::IndexPage
    include Response
    
    def initialize(@title : String)
    end

    def render
      h6 @title, class: "mg-b-0"
    end
  end
end

Rendering Templates

Azu::Response main job is to render the body of the responses to be sent back to browsers and API clients. Most of the time, we use templates to build said responses.

Templates work great for many reasons, some of those, easy to share with designers and front-end developers, portable across teams, and clear separation from presentation and back-end code.

To use templates include the Templates::Renderable module and use the render/2 method

module MyApp
  struct Users::ShowPage
    include Response
    include Templates::Renderable

    TEMPLATE = "users/show.jinja"
    
    getter username : String

    def initialize(@username : String)
    end

    def render
      render template, {"user_name" => username}
    end
  end
end

Last updated