Elixir RESTful Framework
moxley and falood Fix README examples (#113)
* Fix example config/config.exs

* Add missing example for supervisor child
Latest commit 0691c77 Sep 29, 2018
Permalink
Failed to load latest commit information.
config code format Feb 21, 2018
lib code format Aug 24, 2018
test code format Aug 24, 2018
.formatter.exs update .formatter.exs Feb 21, 2018
.gitignore add ex_doc Sep 26, 2015
.travis.yml update travis script Aug 24, 2018
CHANGELOG.md Release v0.13.2 Aug 24, 2018
LICENSE add LICENSE Jul 21, 2014
README.md Fix README examples (#113) Sep 28, 2018
mix.exs Release v0.13.2 Aug 24, 2018

README.md

Maru

REST-like API micro-framework for elixir inspired by grape.

Build Status Hex.pm Version Docs Hex.pm Downloads

Installation

To get started with Maru, add the following to mix.exs:

def deps() do
  [
    {:maru, "~> 0.13"},
    {:cowboy, "~> 2.3"},

    # Optional dependency, you can also add your own json_library dependency
    # and config with `config :maru, json_library, YOUR_JSON_LIBRARY`.
    {:jason, "~> 1.0"}
  ]
end

Usage

lib/my_app/server.ex:

defmodule MyApp.Server do
  use Maru.Server, otp_app: :my_app
end

defmodule Router.User do
  use MyApp.Server

  namespace :user do
    route_param :id do
      get do
        json(conn, %{user: params[:id]})
      end

      desc "description"

      params do
        requires :age, type: Integer, values: 18..65
        requires :gender, type: Atom, values: [:male, :female], default: :female

        group :name, type: Map do
          requires :first_name
          requires :last_name
        end

        optional :intro, type: String, regexp: ~r/^[a-z]+$/
        optional :avatar, type: File
        optional :avatar_url, type: String
        exactly_one_of [:avatar, :avatar_url]
      end

      # post do
      #   ...
      # end
    end
  end
end

defmodule Router.Homepage do
  use MyApp.Server

  resources do
    get do
      json(conn, %{hello: :world})
    end

    mount Router.User
  end
end

defmodule MyApp.API do
  use MyApp.Server

  before do
    plug Plug.Logger
    plug Plug.Static, at: "/static", from: "/my/static/path/"
  end

  plug Plug.Parsers,
    pass: ["*/*"],
    json_decoder: Jason,
    parsers: [:urlencoded, :json, :multipart]

  mount Router.Homepage

  rescue_from Unauthorized, as: e do
    IO.inspect(e)

    conn
    |> put_status(401)
    |> text("Unauthorized")
  end

  rescue_from [MatchError, RuntimeError], with: :custom_error

  rescue_from :all, as: e do
    conn
    |> put_status(Plug.Exception.status(e))
    |> text("Server Error")
  end

  defp custom_error(conn, exception) do
    conn
    |> put_status(500)
    |> text(exception.message)
  end
end

In your Application module, add Server as a worker:

defmodule MyApp.Application do
  use Application

  def start(_type, _args) do
    children = [
      MyApp.Server
    ]

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

Then configure maru:

# config/config.exs
config :my_app, MyApp.Server,
  adapter: Plug.Adapters.Cowboy2,
  plug: MyApp.API,
  scheme: :http,
  port: 8880

config :my_app,
  maru_servers: [MyApp.Server]

For more information, check out Guides and Examples