Crowdhailer

Crowdhailer

Creator of Raxx

Raxx is an alternative to Plug and is inspired by projects such as Rack(Ruby) and Ring(Clojure).

1.0-rc.1 is now available. To use it requires a server, the examples here can be experimented with by adding {:ace, "~> 0.15.2"} to a projects dependencies, NOTE 1.0-rc.0 is equivalent to 0.14.0

Raxx models HTTP as message passing between client and server. There are two flavours to this model.

First is the simple case where a complete request is a single message from client to server and a complete response as a single message from server to client. This is the model successfully exploited by Rack.

The second cases is for streaming where a series of messages are sent in either/both directions. For HTTP this series of messages begins with a head, consisting of all header information plus a few extra details (path for request, status for response). There is then the body broken into 1 or more parts and finally a tail which may contain no further information or may include some trailers.

Simple

           request -->
Client ============================================ Server
                                   <-- response

A server can implement the handle_request/2 callback to use this model in the simplest cases.
For example:

defmodule HomePage do
  use Raxx.Server

  @impl Raxx.Server
  def handle_request(%{method: :GET, path: []}, _state) do
    response(:ok)
    |> set_header("content-type", "text/plain")
    |> set_body("Hello, World!")
  end
end

Streaming

           tail | data(1+) | head(request) -->
Client ============================================ Server
           <-- head(response) | data(1+) | tail

A server can implement the handle_head/2, handle_data/2 & handle_tail/2 callbacks to react to parts of the request as they become available

defmodule Upload do
  use Raxx.Server

  @impl Raxx.Server
  def handle_head(%{method: :PUT, path: ["upload"] body: true}, _state) do
    {:ok, io_device} = File.open("my/path")
    {[], {:file, device}}
  end

  @impl Raxx.Server
  def handle_data(data, state = {:file, device}) do
    IO.write(device, data)
    {[], state}
  end

  @impl Raxx.Server
  def handle_tail(_trailers, state) do
    response(:see_other)
    |> set_header("location", "/")
  end
end

Raxx.Server has one final callback handle_info/2 for dealing with updates from other processes within the application. Several more examples are available in the README.

Goals

Raxx is designed as an alternative to Plug but not a replacement. This thread is meant to be just about Raxx developments, see this previous topic for why I started developing an alternative to plug.

  • model the communication between Client and Server as messaging to be consistent with the erlang/Elixir world view.
    This is the main difference to plug which uses a connection model.
  • support all HTTP patterns including streaming of requests and/or responses.
    In this way it is an evolution of Rack.
  • Require only pure functions, even when implementing a stateful server.
    Familiar anyone who has implemented a GenServer.

Showing Posts 1 to 10

samphilipd

samphilipd

Do you get HTTP2 support automatically when you use Raxx?

Crowdhailer

Crowdhailer OP

Creator of Raxx

Yes

Raxx has evolved to make streaming interactions natural, a requirement for getting all the value from HTTP/2. Ace (the first server offering a Raxx interface) will server content via HTTP/1.1 or HTTP/2 dependent on the client, as long as the server is using TLS(ssl).

Crowdhailer

Crowdhailer OP

Creator of Raxx

Raxx.MethodOverride Middleware for overriding a requests method.

This is the first middleware extracted. It works for applications using streamed or atomic requests.

My plan is to add a few key middleware of the coming month. The Raxx stack will then become a productive toolkit without any of the prescriptive nature of a full framework.

Crowdhailer

Crowdhailer OP

Creator of Raxx

Raxx.Static Middleware for serving static content.

Another middleware added.

example usage:

defmodule MyApp.WWW do
  use Raxx.Server
  use Raxx.Static, "./public"

  @impl Raxx.Server
  def handle_request(request, state) do
  # etc ...
end
michalmuskala

michalmuskala

I wonder about the decision to make middlewares compile-time. I generally consider the fact that plugs are compile-time the biggest design flaw for plug - it’s often very limiting and annoying. The counter-argument is that it’s better for performance, but I’m not really sure it’s such a huge difference. I could easily see a setup, where plugs are initialized once on server start instead of compile-time.

This is especially true of a “static” middleware - usually you want the path configured at runtime, not compile-time.

Crowdhailer

Crowdhailer OP

Creator of Raxx

At the moment there is no rules for middleware. I’m just using native elixir constructs, i.e. defoverridable.
I have deliberately held off defining how middleware should work because I want to discover the best way. A solution that checks works at runtime should not be hard. It’s only functions after all and anything can be passed in as the config argument to handle_request(request, config)

Crowdhailer

Crowdhailer OP

Creator of Raxx

Raxx 0.14.3 released.

Typespecs added to all public functions and dialyzer checks added to CI.

Crowdhailer

Crowdhailer OP

Creator of Raxx

Raxx 0.14.4 released.

  • Add’s two functions to provide helpful errors when starting a server is_application? and verify_application.
Crowdhailer

Crowdhailer OP

Creator of Raxx

Looking for help with middleware.

The Raxx interface is mostly stable, we are on release candidates for a 1.0 and just waiting for experience and feedback from a few more projects before committing to a 1.0. At this point adding middleware to the project is really valuable.

Middleware are isolated projects that anyone could own while being part of a larger effort to simplify web development in Elixir. They should be only of moderate difficulty (depending on which middleware of course). I would naturally offer any help needed in getting familiar with the API.

If interested check out the new issues on the Raxx project

Update several more issues add, beginner friendly issues now marked with the beginner tag.

Crowdhailer

Crowdhailer OP

Creator of Raxx

Raxx 0.14.7 release includes new logging middleware.

Add request logging to raxx application with use Raxx.Logger.

Where Next? Top

Trending in Announcing Top

wojtekmach
Hey everyone! Req is an HTTP client for Elixir that I’ve been working on for quite some time. There is already a lot of HTTP clients out...
New
handnot2
Samly can be used to enable SAML 2.0 Single Sign On in a Plug/Phoenix application. This library uses Erlang esaml to provide plug enabl...
New
woylie
Flop is an Elixir library that applies filtering, ordering and pagination parameters to your Ecto queries. offset-based pagination with...
New
MRdotB
I needed to reuse React components from my Chrome extension in my Phoenix/LiveView backend. I noticed that for Svelte/Vue, there are live...
New
garrison
Hobbes is a low-level distributed database for the Elixir programming language. Hobbes provides a simple, safe, and scalable storage lay...
New
marciok
Hi there! We created Gust: A task orchestrator inspired by Airflow. For those who have never heard about Aiflow, it’s a Python-based wor...
New
fuelen
Hi all! I want to present a small library which provides a mix task for generating an Entity-Relationship Diagram for Ecto schemas. You...
New

Other Trending Topics Top

mudasobwa
I am happy to introduce the very α version of the new programming language compiled to BEAM. Welcome Cure. It has literally three kille...
New
AstonJ
This showed up on my feed.. anyone heard of it? Just hype? Ox Alpha is a reasoning model designed for coding, sustained ag...
New
sergio
It’s not that it’s vocabulary is too advanced. It’s something worse. I get lost trying to follow even a paragraph written by Claude. It’...
New
sorenone
Today we’re releasing Oban for Python. Not an Oban client in Python. Not a pythonx wrapper embedded in Elixir. Nope, it’s a fully operati...
New
akoutmos
@hugobarauna, Dr. Dimitrios Koutmos (my brother) and I (Alex Koutmos) have been hard at work on writing a book on how you can use Elixir ...
New
pferriby
Introductory paragraph I’ll be looking for a keen junior or someone that has a couple of years experience in the real world (so you’ve be...
New

We're in Beta

About us Mission Statement

Options

Thread Display Mode




Thread Preview

Skip Thread Previews