## 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.

## 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`.

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/)