create account

Cooking Up an API Using Maru in Elixir by nphacker

View this thread on: hive.blogpeakd.comecency.com
· @nphacker · (edited)
$0.22
Cooking Up an API Using Maru in Elixir
## Introduction
Application programming interfaces (APIs) are common tools to enable developers to deal with different types of data. Companies use APIs internally to handle lots of processes such as dealing with customer data, working with company analytics, as well as creating their software products.

![Cooking an API](https://lute.io/cooking-api-maru/post.png)

## Enter Maru a REST-like framework for Elixir
[Maru](https://maru.readme.io/docs) is a REST-like framework for Elixir which enables developers to build expressive APIs. Maru includes many useful features for API development such as versioning, routing, parameters, and middleware. In this tutorial we will create a simple recipe API which will return the ingredients to create various food items such as cake, apple pie, and salad.

## Setting up the project
To get started with a basic Maru project follow the steps on the [official Maru website](https://maru.readme.io/docs/basic-usage) to get started with a basic project. You can also `git clone` our Maru starter [here](https://github.com/Elixir-Luthier/simple_maru_starter).

## Routes with Maru
Here is an example of a very simple GET index route created with Maru:
```
get do
    json(conn, %{ hello: :world })
end
```
This route is indicating that the an object containing `hello` as a key and the atom :world as a value returns upon making a request to the '/' route. The route location can be modified simply by adding the route after the `get`. Let's write a route which will return all the food items we can get a recipe for.
```
defmodule MaruCooking.Router.Homepage do
  use Maru.Router
  @moduledoc """
    This is a simple router created with Maru
  """
  @foodItems %{ results: [:cheese_pizza,
                           :cake,
                           :caesar_salad,
                           :cheese_burger,
                           :omelet,
                           :grilled_cheese,
                           :breadsticks,
                           :tiramisu,
                           :crostini,
                           :sicilian_spaghetti ]}
  # :all refers to the /all route this route is accessible via localhost:8880/all
  get :all do
    json(conn, @foodItems)
  end
end
```
### Route parameters
Maru also has built-in parameter validation, and types built in. Take for example:
```
params do
  requires :item, type: Atom
end
get :ingredients do
  json(conn, MaruCooking.FoodData.ingredients(params[:item]))
end
```
The above example is for the route "/ingredients" and accepts a query parameter called item which is typed as an Atom. Maru supports many parameters such as: `String`, `Integer`, `Float`, `Boolean`, `CharList`, `Atom`, `File`, `Json`, `Base64`.

![Ingredients](https://lute.io/cooking-api-maru/ingredients.png)
In this API users can get ingredients for different items defined on the menu.

### Post requests
In addition to get requests Maru also supports creation of post routes:
```
params do
  requires :item, type: Atom
end
post :eat do
  json(conn, MaruCooking.FoodData.eat(params[:item]))
end
```

### Middleware
Maru also supports adding custom middleware. This is useful for example, if you have any custom before route authentication steps or are doing any data initialization. In our example we're going to keep it simple and just print "Asking the head chef."

```
defmodule Before do
  use Maru.Middleware

  def call(conn, _opts) do
    IO.puts "Asking the head chef..."
    conn
  end
end
```

We also have to plug in the Before middleware into the API module as below:
```
defmodule MaruCooking.API do
  use Maru.Router

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

  plug Before
  mount MaruCooking.Router.Homepage
  ...
```
Now when we make a request to the API such as http://localhost:8000/all it should print "Asking the head chef..." before every request.

### Conclusion
Hopefully this has been a good short introduction to how to use Maru, in addition to the features above Maru also supports versioning, exceptions, and useful built-in testing functionality. Maru can also be used in addition to Elixir's [Phoenix web framework](http://www.phoenixframework.org/) in order to make it easier to develop web applications which I will cover in a future post.
### Thanks for reading!
If you enjoyed this post please check out our blog at the [ElixirLuthier](https://lute.io/)
👍  , , , , , , , , , , ,
properties (23)
authornphacker
permlinkcooking-up-an-api-using-maru-in-elixir
categorydevelopment
json_metadata{"tags":["development","elixir"],"image":["https://lute.io/cooking-api-maru/post.png","https://lute.io/cooking-api-maru/ingredients.png"],"links":["https://maru.readme.io/docs","https://maru.readme.io/docs/basic-usage","https://github.com/Elixir-Luthier/simple_maru_starter","http://localhost:8000/all","http://www.phoenixframework.org/","https://lute.io/"],"app":"steemit/0.1","format":"markdown"}
created2017-05-12 18:32:24
last_update2017-05-12 18:38:33
depth0
children0
last_payout2017-05-19 18:32:24
cashout_time1969-12-31 23:59:59
total_payout_value0.182 HBD
curator_payout_value0.042 HBD
pending_payout_value0.000 HBD
promoted0.000 HBD
body_length4,437
author_reputation9,918,008,820,689
root_title"Cooking Up an API Using Maru in Elixir"
beneficiaries[]
max_accepted_payout1,000,000.000 HBD
percent_hbd10,000
post_id3,360,786
net_rshares191,301,488,332
author_curate_reward""
vote details (12)