View Source README
FlEx
FlEx it's a micro-framework for backend inspired by the simplicity of Flask and the complication to use Phoenix in very small applications
One of the cores of this micro-framework it's be flexible, you can define your whole app in a single file or split in a lot of more files, basic rules, nothing to be followed
This project doesn't pretend to replace Phoenix, the opposite we LOVE Phoenix and we're taking a lot of inspiration on the use and implementation of Phoenix, but sometimes a lot of stuff it's too overkill for some very small servers and more when you want to create a very small service
The design it's based on Plug so it's FULLY COMPATIBLE WITH ALL THE PLUGS! and you can create your own plugs in the same format and the same way to use, 100% compatibility
Also includes some useful plugs to create/configure your server quickly
Installation
If available in Hex, the package can be installed
by adding fl_ex to your list of dependencies in mix.exs:
def deps do
[
{:fl_ex, "~> 0.1.0"}
]
endThe example
This project includes a complete implementation example (server, routers, testing), just check the folder fl_ex_example
Basic Usage
IMPORTANT! this implementation comes from the point from a empty project, if you have some of the files mentioned just follow the line that says:
add to your file
First you need create a module that will be your server
defmodule MyApp.Server do
use FlEx.Server, otp_app: :my_app
plug Plug.Head
plug Plug.RequestId
plug Plug.Logger, log: :debug
plug FlEx.Plug.Accepts, ["json"]
plug MyApp.Plugs.Auth
# define directly your route
get "/your_page/:param", &my_func/2
# also you can define a function from other module
get "/your_page/:param", MyApp.SomeOtherModule, :function_name
# or define a scope of routes
scope "/api/v1" do
# you can add your plugs that just will run on this scoped routes
plug MyApp.Plugs.Auth
get "/your_page", &my_func/2
get "/your_page", MyApp.SomeOtherModule, :function_name
# you can add exclusive plugs to just one route if you want
get "/your_page", MyApp.SomeOtherModule, :function_name, Plug.ExamplePlug, {Plug.OtherExamplePlug, [opts: 1]}
end
def my_func(conn, %{"param" => param} = _params) do
conn
|> FlEx.Renderer.status(200)
|> FlEx.Renderer.json(%{some_key: "value of param is #{param}"})
end
endThen create your Application module, this must have the previous server added to the childer list
defmodule MyApp.Application do
use Application, otp_app: :my_app
@impl true
def start(_type, _args) do
# List all child processes to be supervised
children = [
MyApp.Server # add to your file
]
opts = [strategy: :one_for_one, name: MyApp.Supervisor]
Supervisor.start_link(children, opts)
end
endThen add your Application module to your application list to start in your mix.exs file, in case that this isn't done
yet
def application do
[
mod: {MyApp.Application, []},
extra_applications: [:logger]
]
endWith this you have the basic server working now and you can start using it
Routes
The FlEx.Server allows to define routes and plugs directly, but what if you want to define your routes in other places
and just merge all the routes in the server, for this you need FlEx.Router
defmodule MyApp.SomeRouter do
use FlEx.Router
plug :accepts, ["json"]
scope "/api/v1" do
get "/your_page", MyApp.SomeOtherModule, :function_name
end
endand add to the server module the next line
defmodule MyApp.Server do
use FlEx.Server, otp_app: :my_app
define_router MyApp.SomeRouter
endConfigure
You can configure your server in the config/config.exs file
import Config
config :fl_ex_example, FlEx.Server,
port: System.get_env("PORT"),
json_handler: Jason| key | type | default | desc |
|---|---|---|---|
| port | :string | 4000 | server port |
| json_handler | Module | Jason | The module that partses string to map and viseversa |
How to test
You can test your server using the module FlEx.ConnTest sharing with key endpoint your implemented server
defmodule FlExExample.ServerTest do
use FlEx.ConnTest, endpoint: FlExExample.Server
setup %{conn: conn} do
{:ok, conn: put_req_header(conn, "accept", "application/json")}
end
test "should work /your_page/:param", %{conn: conn} do
conn = get(conn, "/your_page/some_value")
assert %{"some_key" => _} = json_response(conn, 200)
end
endOr to test by "controllers" or routers, create your conn test module
defmodule FlExExample.ConnTest do
defmacro __using__(_) do
quote do
use FlEx.ConnTest, endpoint: FlExExample.Server
setup %{conn: conn} do
{:ok, conn: put_req_header(conn, "accept", "application/json")}
end
end
end
endand just implement the module directly in your test
defmodule FlExExample.ServerTest do
use FlExExample.ConnTest
test "should work /your_page/:param", %{conn: conn} do
conn = get(conn, "/your_page/some_value")
assert %{"some_key" => _} = json_response(conn, 200)
end
endRoadmap
- [x] Working
- [ ] Live code changes
- [ ] Render
- [x] JSON
- [ ] HTML
- [x] Compatible with Plugs (100%)
- [x] Plugs for whole router
- [x] Plugs exclusive for
scope - [ ]
pipelineto create plug flows and refeer toscopeor route - [x] Private plugs for specific routes
- [ ] Testing
- [x] Basic json testing
- [ ] More helpers
- [x] Server
- [x] Separated routers