• Stars
    star
    136
  • Rank 258,057 (Top 6 %)
  • Language
    Elixir
  • License
    MIT License
  • Created over 2 years ago
  • Updated 5 months ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

An HTTP framework built on top of elli

Aino

Discord

An experimental HTTP framework built on top of elli. Aino is pronounced as "eye no".

Why Aino?

Aino is an experiment to try out a new way of writing HTTP applications on Elixir. It uses elli instead of Cowboy like Phoenix and Plug. Instead of writing an Endpoint like Phoenix, you write a Handler. The handler's job is to reduce across a series of middleware that are simple functions to generate a response.

The handler also works on a token instead of a conn. The token is a simple map that you can add whatever keys you wish to it. Aino has a few standard keys but you can easily ignore them if you want to write your own processing.

How to use Aino

In order to use Aino, you must add it to your supervision tree and provide a callback handler that Aino will call handle/1 on.

defmodule Aino.Application do
  use Application

  def start(_type, _args) do
    # get your config somehow

    aino_config = %Aino.Config{
      callback: Example.Web.Handler,
      otp_app: :example,
      host: config.host,
      port: config.port,
      environment: config.environment,
      config: %{}
    }

    children = [
      {Aino.Supervisor, aino_config}
    ]

    opts = [strategy: :one_for_one, name: Aino.Supervisor]
    Supervisor.start_link(children, opts)
  end
end

In the handler, you process the incoming request (in the token) through a series of "middleware." The middleware all accept a single parameter, the token. A token is simply a map that you can store whatever you want on it.

The only thing that is initially pased in is the :request, and at the very end of the handle/1 the token should include three keys, :response_status, :response_headers, and :response_body.

Aino ships with a common set of middleware that you can include at the top of processing, if you don't want them, simply don't include them! The list of middleware can be a list of lists as well.

Another built in middleware is a simple routing layer. Import the HTTP methods from Aino.Middleware.Routes that you're going to use in your routes. Then each HTTP method function takes the route and a middleware that should be run on the route.

defmodule MyApp.Handler do
  import Aino.Middleware.Routes, only: [get: 2, get: 3, post: 2]

  @behaviour Aino.Handler

  def routes() do
    [
      get("/", &Index.index/1, as: :root),
      get("/about", &Index.about/1, as: :about),
      order_routes()
    ]
  end

  defp order_routes() do
    [
      get("/orders", &Orders.index/1, as: :orders),
      get("/orders/:id", &Orders.show/1, as: :order),
      post("/orders", &Orders.create/1)
    ]
  end

  @impl true
  def handle(token) do
    middleware = [
      Aino.Middleware.common(),
      &Aino.Middleware.Routes.routes(&1, routes()),
      &Aino.Middleware.Routes.match_route/1,
      &Aino.Middleware.params/1,
      &Aino.Middleware.Routes.handle_route/1,
    ]

    Aino.Token.reduce(token, middleware)
  end
end

The route middleware take a token and generally should return the three keys required to render a response. You can also render EEx templates as shown below.

defmodule Index do
  alias Aino.Token

  def index(token) do
    token
    |> Token.response_status(200)
    |> Token.response_header("Content-Type", "text/html")
    |> Token.response_body(Index.View.render("index.html"))
  end
end

defmodule Index.View do
  require Aino.View

  Aino.View.compile [
    "lib/index/index.html.eex"
  ]
end

Concepts

Aino.Handler

A handler processes an incoming request from Aino.

The handle/1 function is passed an Aino.Token.

The handler must return a token that contains three keys to return a response:

  • :response_status
  • :response_headers
  • :response_body

If the token does not contain these three keys, a 500 error is returned.

Inside your handler, you may wish to use several Aino.Middleware including Aino.Middleware.common/0.

Aino.Token

The token is what flows through the entire web request. Tokens are simple maps that contain no defined keys beyond :request. Several Aino middleware add keys and they are documented in the functions.

Aino.Middleware

Middleware are simple functions that take the token and return the token. They process the request and add or modify existing keys on the token.

An example middleware is Aino.Middleware.headers/1:

def headers(%{request: request} = token) do
  headers =
    Enum.map(request.headers, fn {header, value} ->
      {String.downcase(header), value}
    end)

  Map.put(token, :headers, headers)
end

More Repositories

1

ex_venture

Text based MMORPG engine written in Elixir
Elixir
651
star
2

kalevala

A world builder's toolkit in Elixir
Elixir
163
star
3

grapevine

The MUD Chat Network
Elixir
152
star
4

squabble

Simple leader election for Elixir applications
Elixir
74
star
5

hypermedia_rails

An example Rails app with a hypermedia API
Ruby
33
star
6

gossip-elixir

An Elixir client for Grapevine
Elixir
20
star
7

bookshare

Bookshare
Ruby
5
star
8

spigot

A telnet test server for Grapevine's web client
Elixir
5
star
9

gossip-clients

Clients for the Gossip Chat Network
Python
5
star
10

venture_bot

A bot for ExVenture
Elixir
4
star
11

grapevine-legacy

Grapevine player portal, part of the Gossip Network
Elixir
4
star
12

tapio

A Twitter clone to stress test Aino development
Elixir
3
star
13

grapevine-telnet

Telnet client application for Grapevine
Elixir
3
star
14

elias

UCL parser in Elixir
Elixir
3
star
15

letter

rspec style lets for classes
Ruby
3
star
16

telnet-elixir

Elixir
3
star
17

aino_new

Elixir
3
star
18

gossip-ranvier

A ranvier bundle for Gossip
JavaScript
3
star
19

nagare

A simple serializer for your Rails API.
Ruby
2
star
20

rad_example

Site hosted at http://rad-example.herokuapp.com/
Ruby
2
star
21

dotfiles

My dotfiles
Vim Script
1
star
22

ruby-mud

A MUD written in ruby
Ruby
1
star
23

jsr223_test

Java
1
star
24

lyhyt

URL shortener example for Aino
Elixir
1
star
25

listmaker

Warhammer list maker
JavaScript
1
star
26

aino_example

Very minimal example app (base for aino_new)
Elixir
1
star
27

gol-backbone

Game of Life in Backbone.js
JavaScript
1
star
28

todolist

A project app for trying out Backbone.js and Rails 3.1
JavaScript
1
star
29

mixin_it_up_datastore

Mixin' It Up: Datastore Edition
Ruby
1
star
30

heycake

heycake is a way to track callouts for your team in slack
Elixir
1
star
31

grouter

A router written in go
Go
1
star
32

gossip-backbone

Common sync code for the Gossip "backbone"
Elixir
1
star
33

grapevine-mobile

Mobile client for Grapevine
JavaScript
1
star
34

blog.oestrich.org

CSS
1
star
35

aino-rss

Elixir
1
star
36

grapevine-docker

Docker images for Grapevine and other projects
Dockerfile
1
star
37

raisin

Moderation tools for the Gossip Network
Elixir
1
star
38

lncln

lncln CMS, this was an old project I had
PHP
1
star