HTTP is message passing

Or - Why I stopped using Plug

In conclusion, Plug is not idiomatic Elixir (or erlang) because of its impure interface. My solution is a pure interface called Raxx.

HTTP describes communication between clients and servers via the web. Below is a quote from the rfc7230 introduction.

The Hypertext Transfer Protocol (HTTP) is a stateless application- level request/response protocol that uses extensible semantics and self-descriptive message payloads for flexible interaction with network-based hypertext information systems.

This introduction describes both requests and responses as messages. Communication between web endpoints is therefore a system using message passing.

GenServer

Message passing is a completley natural concept to Elixir. OTP even provides an idiomatic way to build servers, using the GenServer module.

Below is a simple GenServer implementation that will send a response to a client request message. In this example the client is just another beam process.

defmodule MyServer do use GenServer def handle_call(:request, _from, state) do {:reply, :response, state} end end

Raxx.Server

Raxx.Server is designed for idiomatic handling of request and response messages. The only difference is the messages are from a web client instead of beam process.

Below is a simple Raxx.Server implementation. You can see the similarities to the GenServer example.

defmodule MyApp do use Raxx.Server def handle_request(_request, _state) do response(:ok) end end

A Raxx.Server is started for each request; therefore handle_request is the first function called and an init callback is not required.

is started for each request; therefore is the first function called and an callback is not required. Each HTTP message exchange is isolated to its own process; there is no need for a from argument to be passed to handle_request .

argument to be passed to . There is no need to return a new state in Raxx.Server implementation, the process is terminated as soon as the reponse is sent.

What about streaming

One of the design goals for Plug was to accomodate streaming. This was an argument against interfaces like Rack, where a complete request or response would need to be loaded into memory.

Raxx is loosely based on Rack but does not have these drawbacks. Streaming can be managed in an efficient manner using other callbacks available on Raxx.Server , see the docs for details.

The Raxx toolkit

Raxx is a toolkit for refined web development. It is currently used in production by several companies.

At the core of the project are data structures for Raxx.Request and Raxx.Response . Both are pure data structures which means that they contain no references to processes. This is different to Plug.Conn which does contain a process. This process is the source of odd behaviour such as only being able to read the body once.

A server is needed to run any web application. Ace is the first server to run raxx applications and has support for HTTP/1.x and HTTP/2.

Several common components are part of the core libray such as Raxx.Router and Raxx.Logger . More are available in other projects such as Raxx.APIBlueprint for a documented router

Finally there is Raxx.Kit . It is the quickest way to get started with Raxx. This project consists of generators to set up a project with sensible defaults, as well as the Ace server for your application.

Questions?

If you want to find out more the best thing is to ask on the Elixir Forum or chat to us in the #raxx slack channel.