Jump to content
Aerosol

Weber - High Performance web framework for ElixirLang

Recommended Posts

Posted

Weber - is a open souce weber framework for Elixir programming language. It's very lightweight and easy to deploy. Main goal of Weber to help developers to develop scalable web applications in the usual rails-like style. Weber is in eary development stage now, first commit was 07.09.2013, but now it has many features like:

  • Project generation
  • Json parsing/generation
  • Websockets
  • Sessions
  • i18n [experimental]
  • Grunt.js integraion
  • HTML helpers
  • and many more

many features are in plans or in progress now like code reloading and etc...

Architecture

I started Weber as a hobby project and main point for was - to make high performace web framework. There are many optimizations in weber in different places, more details you can find in the previous post. Weber's workflow is easy. Web server gets request from user and pass it to the handler. Handler tried to parse and match request url and execute any action which dependes on request:

Weber.png

Routing

All weber's routing configuration is in route.ex file. There is: route marcros in Weber. Main goal of router is to connect URLs with controllers and actions. You no need to declare route macros in your project for configuring routing. It's already predefined after new project creation. Example of routing configuration:

route on("GET", "/", :Simpletodo.Main, :action)
|> on("POST", "/add/:note", :Simpletodo.Main, :add)

You can see here that weber's router consist from route macros and on/4 clauses. Every on/4 gets four parameters which means what to response for certain url.

  • "GET" - HTTP method. Can be "GET","POST","PUT", "DELETE", "PATCH", "ANY"
  • "/" - url
  • :SimpleTodo.Main - controller
  • :add - action

So if weber gets "/" request, it will call :SimpleTodo.Main.add, will get response of it and will return user. Weber router supports different features: Regular expression in path:

route on("ANY", %r{/hello/([\w]+)}, :Simpletodo.Main, :action)

Controller/Action declaration with '#':

route on("GET", "/", "Simpletodo.Main#action")

Redirect:

route redirect("GET", "/redirect", "/weber")

Resource routing

route resource(:Controller.Work)

Will generate:

route on("GET",    "/controller/work/:id",        :Controller.Work, :show)
|> on("POST", "/controller/work/:id/create", :Controller.Work, :create)
|> on("GET", "/controller/work/:id/edit, :Controller.Work, :edit)
|> on("PUT", "/controller/work/:id/update, :Controller.Work, :update)
|> on("DELETE", "/controller/work/:id/delete, :Controller.Work, :delete)

Controllers

Main Unit in Weber is a controller. Every controller consists from action. Controller is a ussual Elixir module and Action is a ussual Elixir function with two parameters. For example:

defmodule Simpletodo.Main do

def action(_, conn) do
{:render, [project: "simpleTodo"], []}
end

def add([body: body], conn) do
{:json, [response: "ok"], [{"Content-Type", "application/json"}]}
end

end

Action parameters:

  • bindings - url bindings. If you have a route path: /add/:name, you will get here: [name: name]
  • connection - Plug record (connection info)

Every action must return one of predefined tuple. It can be:

  • {:render, [project: "simpleTodo"], [{"HttpHeaderName", "HttpHeaderValheaderVal"}]} - Renders views from views/controller/action.html and sends it to response. Or without headers. {:render, [project: "simpleTodo"]}
  • {:render_inline, "foo <%= bar %>", [bar: "baz"]}} - Renders inline template.
  • {:render_other, Elixir.Views.Index, [foo: "foo"], []} - Renders any view in controller. Or without headers.
  • {:file, path, headers} - Sends file in response. Or without headers {:file, path}
  • {:json, [response: "ok"], [{"HttpHeaderName", "HttpHeaderValheaderVal"}]} - Weber converts keyword to json and sends it to response. Or without headers: {:json, [response: "ok"]}
  • {:redirect, "/main"} - Redirects to other resource.
  • {:text, data, headers} - Sends plain text. Or without headers: {:text, data}
  • {:nothing, ["Cache-Control", "no-cache"]} - Sends empty response with status 200 and headers.

Every action can have own view. So if you have routing something like this:

route on ("ANY", "/", :MyProject.Main, :index)

And action:

def index(_, _) do
{:render, []}
end

Weber will render lib/views/main/index.html view.

Templates

Weber use EEx templates. It's like HAML in rails:

<!DOCTYPE HTML>
<html>
<head>
<title>Simplechat</title>
</head>

<body>
<span>Hello, <%= @project %></span>
</body>
</html>

There are many HTML EEx helpers in the Weber:

  • Weber.Helper.Html - build html from Elixir
  • content_for - layout helper
  • include_view - include html part to the another html
  • Resource helper - script/css/audio/video...

Models

Weber has no opportunity to use/build data models, instead you can use Ecto library. Ecto is a domain specific language for writing queries and interacting with databases in Elixir. See examples.

Benchmark

As i said above i tried and trying now to make weber high perfomance. I found table of comparing json transfering, here is my table with the same test:

Platform	Req/s 1000
NodeJS 27
Plain cowboy 32
ChicagoBoss 7.2
Zotonic 7.5
Weber 16.8

Links

Weber at github - Weber

weber-contrib - weber-contrib

Source

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.



×
×
  • Create New...