Creating Scalable RESTful APIs: A Practical Guide to Using Elixir and Phoenix Framework
In the world of modern web development, building RESTful APIs is an essential skill. Elixir, a dynamic, functional language, and Phoenix, a web development framework built on top of Elixir, offer an excellent environment for building scalable, efficient, and reliable RESTful APIs. This is one of the reasons why many companies opt to hire Elixir developers. In this blog post, we’ll walk you through developing a RESTful API using these technologies, providing insights into the skill sets that make Elixir developers valuable to modern web development.
1. What are Elixir and Phoenix?
Elixir is a dynamic, functional language designed for building scalable and maintainable applications. Elixir leverages the Erlang VM, which is known for running low-latency, distributed, and fault-tolerant systems.
Phoenix is a web framework built with Elixir. It provides the productivity of frameworks like Ruby on Rails while also being able to handle a large number of concurrent clients, making it excellent for real-time applications. It includes everything needed to build a web application – routing, MVC, database access, and tasks for common needs.
2. Getting Started
Before we start, you’ll need to have Elixir installed on your machine. If you haven’t already, you can find instructions on the [Elixir-lang website] (https://elixir-lang.org/install.html). This knowledge base is also beneficial if you’re looking to hire Elixir developers, as it gives you an understanding of the prerequisites they need to work effectively. Once you have Elixir installed, you can install the Phoenix framework by running the following command, a task familiar to any Elixir developer.
```bash mix archive.install hex phx_new ```
We are now ready to create our new Phoenix application.
```bash mix phx.new my_api --no-html --no-webpack ```
The `–no-html –no-webpack` flags tell Phoenix that we’re building an API and don’t need any of the components related to a front-end application.
3. Building Our API
Let’s create a simple API for managing a list of tasks. Each task will have an `id`, `title`, and `completed` status.
First, we’ll generate a new Phoenix resource.
```bash mix phx.gen.json Tasks Task tasks title:string completed:boolean ```
This command will generate a new controller, model, view, and repository files for our tasks. It will also generate a new migration file for creating the tasks table in our database.
To apply this migration, run:
```bash mix ecto.migrate ```
Let’s examine the main pieces of code generated.
3.1 The Model
Located at `lib/my_api/tasks/task.ex`, the model defines our Ecto schema, changesets, and any business logic related to our tasks. Ecto is the database wrapper and query generator for Elixir.
```elixir
defmodule MyApi.Tasks.Task do
use Ecto.Schema
import Ecto.Changeset
schema "tasks" do
field :title, :string
field :completed, :boolean
timestamps()
end
@doc false
def changeset(task, attrs) do
task
|> cast(attrs, [:title, :completed])
|> validate_required([:title, :completed])
end
end
```
Here, we have a `changeset` function, which is used for creating or updating tasks. The `cast` function is used to filter the parameters we allow and `validate_required` is used to ensure that the parameters are present.
3.2 The Controller
Located at `lib/my_api_web/controllers/task_controller.ex`, the controller handles HTTP requests, interacts with the model, and returns the appropriate HTTP responses.
```elixir
defmodule MyApiWeb.TaskController do
use MyApiWeb, :controller
alias MyApi.Tasks
alias MyApi.Tasks.Task
def index(conn, _params) do
tasks = Tasks.list_tasks()
render(conn, "index.json", tasks: tasks)
end
def create(conn, %{"task" => task_params}) do
case Tasks.create_task(task_params) do
{:ok, task} ->
conn
|> put_status(:created)
|> put_resp_header("location", Routes.task_path(conn, :show, task))
|> render("show.json", task: task)
{:error, %Ecto.Changeset{} = changeset} ->
conn
|> put_status(:unprocessable_entity)
|> render(MyApiWeb.ChangesetView, "error.json", changeset: changeset)
end
end
# Additional controller actions for show, update, and delete are similar
end
```
Each function in the controller corresponds to an HTTP action. The `index` function lists all tasks, and the `create` function creates a new task.
3.3 Routing
Phoenix uses a RESTful routing system, much like Ruby on Rails. If you open up `lib/my_api_web/router.ex`, you’ll see something like this:
```elixir
defmodule MyApiWeb.Router do
use MyApiWeb, :router
pipeline :api do
plug :accepts, ["json"]
end
scope "/api", MyApiWeb do
pipe_through :api
resources "/tasks", TaskController
end
end
```
The `resources “/tasks”, TaskController` line sets up RESTful routing for our tasks.
4. Testing Our API
To test our API, we can use tools like `curl` or Postman. Here’s an example using curl:
```bash
# To fetch all tasks
curl -H "Content-Type: application/json" http://localhost:4000/api/tasks
# To create a new task
curl -X POST -d '{"task":{"title":"New Task","completed":false}}' -H "Content-Type: application/json" http://localhost:4000/api/tasks
```
Wrapping Up
Elixir and Phoenix provide a highly scalable and efficient environment for building RESTful APIs, which is why many companies choose to hire Elixir developers. With features like hot code swapping and the ability to handle many connections, it’s a compelling choice for API development. This blog post has only scratched the surface of what you can do with Elixir and Phoenix. There’s much more to explore, making it worthwhile to consider hiring Elixir developers who can leverage the full potential of these technologies. I encourage you to dive in and start experimenting. Happy coding!
Table of Contents


