All Projects → CrowdHailer → Raxx

CrowdHailer / Raxx

Licence: apache-2.0
Interface for HTTP webservers, frameworks and clients

Programming Languages

elixir
2628 projects

Projects that are alternatives of or similar to Raxx

Lux
Build scalable, Node.js-powered REST JSON APIs with almost no code.
Stars: ✭ 556 (+47.09%)
Mutual labels:  framework, backend
Atlas.js
A component-based Node.js library to reduce boilerplate and provide sane project structure 🍻
Stars: ✭ 108 (-71.43%)
Mutual labels:  framework, backend
Goyave
🍐 Elegant Golang REST API Framework
Stars: ✭ 811 (+114.55%)
Mutual labels:  framework, backend
Cli
GraphQL back-end framework with first-class Typescript support
Stars: ✭ 37 (-90.21%)
Mutual labels:  framework, backend
Sifrr
⚡️ Set of tiny, independent libraries for creating modern and fast webapps with javascript/typescript
Stars: ✭ 174 (-53.97%)
Mutual labels:  framework, backend
Ace tao
ACE and TAO
Stars: ✭ 472 (+24.87%)
Mutual labels:  framework, ace
Micro
Micro is a distributed cloud operating system
Stars: ✭ 10,778 (+2751.32%)
Mutual labels:  framework, backend
Rack App
minimalist framework for building rack applications
Stars: ✭ 389 (+2.91%)
Mutual labels:  web-application-framework, rack
Goldeneye
The CQRS flavoured framework that will speed up your WebAPI and Microservices development
Stars: ✭ 171 (-54.76%)
Mutual labels:  framework, backend
Anpylar
Python client-side web development framework
Stars: ✭ 160 (-57.67%)
Mutual labels:  framework, web-application-framework
October
Self-hosted CMS platform based on the Laravel PHP Framework.
Stars: ✭ 10,740 (+2741.27%)
Mutual labels:  framework, backend
Youi
Next generation user interface and application development in Scala and Scala.js for web, mobile, and desktop.
Stars: ✭ 186 (-50.79%)
Mutual labels:  framework, web-application-framework
Lumber
Install Forest Admin in minutes.
Stars: ✭ 2,077 (+449.47%)
Mutual labels:  framework, backend
Plezi
Plezi - the Ruby framework for realtime web-apps, websockets and RESTful HTTP
Stars: ✭ 239 (-36.77%)
Mutual labels:  framework, rack
Locawebstyle
Locawebstyle - Um framework com padrões para desenvolvimento de interfaces web.
Stars: ✭ 365 (-3.44%)
Mutual labels:  framework
Util
Util是一个.net core平台下的应用框架,旨在提升小型团队的开发输出能力,由常用公共操作类(工具类)、分层架构基类、Ui组件,第三方组件封装,第三方业务接口封装,配套代码生成模板,权限等组成。
Stars: ✭ 3,874 (+924.87%)
Mutual labels:  framework
Polymorph
Polymorph is a real-time network packet manipulation framework with support for almost all existing protocols
Stars: ✭ 364 (-3.7%)
Mutual labels:  framework
Kadence
⚠️ KADENCE HAS MOVED TO GITLAB ⚠️
Stars: ✭ 363 (-3.97%)
Mutual labels:  framework
Shep
A framework for building JavaScript Applications with AWS API Gateway and Lambda
Stars: ✭ 376 (-0.53%)
Mutual labels:  framework
Ark
ARK is a lightweight, agility, elastic, distributed plugin framework written in C++,make it easier and faster to create your own application service.
Stars: ✭ 370 (-2.12%)
Mutual labels:  framework

Raxx

Interface for HTTP webservers, frameworks and clients.

Hex pm Build Status License

See Raxx.Kit for a project generator that helps you set up a web project based on Raxx/Ace.

Simple server

1. Defining a server

defmodule MyServer do
  use Raxx.SimpleServer

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

  def handle_request(%{method: :GET, path: _}, _state) do
    response(:not_found)
    |> set_header("content-type", "text/plain")
    |> set_body("Oops! Nothing here.")
  end
end
  • A request's path is split into segments. A request to GET / has path [].

2. Running a server

To start a Raxx server a compatible HTTP server is needed. This example uses Ace that can serve both HTTP/1 and HTTP/2.

raxx_server = {MyServer, nil}
http_options = [port: 8080, cleartext: true]

{:ok, pid} = Ace.HTTP.Service.start_link(raxx_server, http_options)
  • The second element in the Raxx server tuple is passed as the second argument to the handle_request/2 callback. In this example it is unused and so set to nil.

Start your project and visit http://localhost:8080.

HTTP streaming

An HTTP exchange involves a client sending data to a server receiving a response. A simple view is to model this as a single message sent in each direction. Working with this model corresponds to Raxx.SimpleServer callbacks.

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

When the simple model is insufficient Raxx exposes a lower model. This consists of a series of messages in each direction. Working with this model corresponds to Raxx.Server callbacks.

           tail | data(1+) | head(request) -->
Client ============================================ Server
           <-- head(response) | data(1+) | tail
  • The body of a request or a response, is the combination of all data parts sent.

Stateful server

The LongPoll server is stateful. After receiving a complete request this server has to wait for extra input before sending a response to the client.

defmodule LongPoll do
  use Raxx.Server

  @impl Raxx.Server
  def handle_head(%{method: :GET, path: ["slow"]}, state) do
    Process.send_after(self(), :reply, 30_000)

    {[], state}
  end

  @impl Raxx.Server
  def handle_info(:reply, _state) do
    response(:ok)
    |> set_header("content-type", "text/plain")
    |> set_body("Hello, Thanks for waiting.")
  end
end
  • A long lived server needs to return two things; the message parts to send, in this case nothing []; and the new state of the server, in this case no change state.
  • The initial_state is configured when the server is started.

Server streaming

The SubscribeToMessages server streams its response. The server will send the head of the response upon receiving the request. Data is sent to the client, as part of the body, when it becomes available. The response is completed when the chatroom sends a :closed message.

defmodule SubscribeToMessages do
  use Raxx.Server

  @impl Raxx.Server
  def handle_head(%{method: :GET, path: ["messages"]}, state) do
    {:ok, _} = ChatRoom.join()
    outbound = response(:ok)
    |> set_header("content-type", "text/plain")
    |> set_body(true)

    {[outbound], state}
  end

  @impl Raxx.Server
  def handle_info({ChatRoom, :closed}, state) do
    outbound = tail()

    {[outbound], state}
  end

  def handle_info({ChatRoom, data}, state) do
    outbound = data(data)

    {[outbound], state}
  end
end
  • Using set_body(true) marks that the response has a body that it is not yet known.
  • A stream must have a tail to complete, metadata added here will be sent as trailers.

Client streaming

The Upload server writes data to a file as it is received. Only once the complete request has been received is a response sent.

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
  • A body may arrive split by packets, chunks or frames. handle_data will be invoked as each part arrives. An application should never assume how a body will be broken into data parts.

Request/Response flow

It is worth noting what guarantees are given on the request parts passed to the Server's handle_* functions. It depends on the Server type, Raxx.Server vs Raxx.SimpleServer:

request flow

So, for example, after a %Raxx.Request{body: false} is passed to a Server's c:Raxx.Server.handle_head/2 callback, no further request parts will be passed to to the server (c:Raxx.Server.handle_info/2 messages might be, though).

Similarly, these are the valid sequences of the response parts returned from the Servers:

response flow

Any Raxx.Middlewares should follow the same logic.

Router

The Raxx.Router can be used to match requests to specific server modules.

defmodule MyApp do
  use Raxx.Server

  use Raxx.Router, [
    {%{method: :GET, path: []}, HomePage},
    {%{method: :GET, path: ["slow"]}, LongPoll},
    {%{method: :GET, path: ["messages"]}, SubscribeToMessages},
    {%{method: :PUT, path: ["upload"]}, Upload},
    {_, NotFoundPage}
  ]
end
Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].