Bootstrapping an API-only backend for a Social Networking app using Elixir/Phoenix

While learning any programming language, I tend to document my struggles, about how I overcome stuffs and solve problems. Recently, I started learning Elixir mostly because I wanted to explore its ‘realtime’ feature. As a result, I decided to make an API-only backend for a Social Networking app.

I’m not saying that this article will document you the best ways to create and structure APIs for your project. This will be totally according to my thoughts. So, feel free to share you feedback.

Basically, what I expect to get done as a part of this project is to build a Social Network which will have different features and those features can be toggled from some admin area. Based on which features are enabled, the user can make use of these features.

Our Social Network will have the following features:

  1. Authentication (obviously) using Google, Facebook and Twitter.
  2. Profile for each user from where they can edit their details.
  3. Realtime Newsfeed which will update itself after a certain interval of time.
  4. An Admin area from where the admins can toggle features for their site and manage their users.

I’ll be using the Phoenix framework to code these APIs. These will include the basic setup of the app, it’s structure and adding tests which also includes setting up Travis.

The code will be available on Github. Feel free to fork and add more features to it!

Bootstrapping a basic Phoenix app

Make sure that you’ve the basic setup required for creating a Phoenix app. You can know about how to install Elixir, Erlang and Phoenix from the Phoenix docs.

After the installation is done properly, you can create a basic Phoenix app using the following command in your terminal:

mix phoenix.new social_app_api --no-html --no-brunch

This will generate a folder named social_app_api and install the necessary dependencies. Since, this will be an api-only app, we don’t need the html as well as Brunch which is used by Phoenix to compile static assets (javascript, css, etc).

Creating the Postgresql Database

Edit the file config/dev.exs and modify the name of you database. It will be something like this:

# Configure your database
config :social_app_api, SocialAppApi.Repo,
adapter: Ecto.Adapters.Postgres,
username: "nirmalyaghosh",
password: "",
database: "social_app_api_dev",
hostname: "localhost",
pool_size: 10

Also modify the config/test.exs which might look something like this:

# Configure your database
config :social_app_api, SocialAppApi.Repo,
adapter: Ecto.Adapters.Postgres,
username: "nirmalyaghosh",
password: "",
database: "social_app_api_test",
hostname: "localhost",
pool: Ecto.Adapters.SQL.Sandbox

Now run the following from your terminal:

mix ecto.setup 

This will create the postgresql database for you which will be used by your app during development and testing.

Now, run the following from your terminal:

mix phoenix.server

This will fire up the Phoenix server and you can see your app at http://localhost:4000/. The page will show the following error:

no route found for GET / (SocialAppApi.Router)

This is because we didn’t add any routes for our app. We will deal with this error later. For now, let’s set up Travis so that the specs run every time we push our code changes to Github.

Setting up Travis

Travis will the service where we will test our app before we deploy the app to production.

Register for a Travis account if you don’t already have it. Now, you need to link your Github account with Travis. After you’re done linking your Github profile with Travis, go to your Travis profile page and enable the repository where you’ve pushed your code.

Enabling the repository on Travis

Now, if you go to the Build History tab inside Travis, you will see that the tests are having some error. This is because your code doesn’t have any .travis.yml which is required by Travis to identify the language and other services that is required by your app.

Create a file named .travis.yml in the root folder of your app with the following code:

sudo: requiredlanguage: elixir
elixir:
- 1.4.1
otp_release:
- 18.2
addons:
apt:
sources:
- precise-pgdg-9.5
packages:
- postgresql-9.5
- postgresql-contrib-9.5
postgresql: '9.5'
services:
- postgresql
before_script:
# Create the test database
- cp config/text.exs.travis config/test.exs
- psql -c 'create database social_app_api_test;' -U postgres
before_install:
- sudo apt-get update
- sudo apt-get install postgresql-9.5
- sudo /etc/init.d/postgresql stop
- sudo /etc/init.d/postgresql start 9.5

Now, create another file config/test.exs.travis with the following contents:

use Mix.Config# We don't run a server during test. If one is required,
# you can enable the server option below.
config :social_app_api, SocialAppApi.Endpoint,
http: [port: 4001],
server: false
# Print only warnings and errors during test
config :logger, level: :warn
# Configure your database
config :social_app_api, SocialAppApi.Repo,
adapter: Ecto.Adapters.Postgres,
username: "postgres",
password: "",
database: "social_app_api_test",
hostname: "localhost",
pool: Ecto.Adapters.SQL.Sandbox

This file will be used while testing you app on Travis. I’ve created this as a separate file so that the file which is used by Travis while testing is different from the one which is being used will testing locally. Generally, I prefer this approach since, in this way, you can have different attributes like database, username, password and hostname for Travis and your local machine.

Now, commit these changes and push your code to Github. You will see a right tick against the commit on Github once the build is passed for that commit on Travis.

All tests are passing on Travis

You can also go to the Build History tab of Travis and see that the build is passing for that commit.

Travis build is successful

Now, whenever you push any changes to Github, Travis will run and show if the builds are passing or failing for you app. Cool, isn’t it?

Note:

There are also other bunch of useful CI tools. Feel free to use any of them you like. I’ve used Travis here since it’s free for Open Source projects.

Setting JSONAPI format

I’ll be following jsonapi format for building out the APIs. It’s really scalable and obviously, you should be following some standards while designing your APIs.

We’ll need to make some minor changes so that our app follows this spec. Open config/config.exs and add the following code:

...
# Change the json response type to json-api
config :phoenix, :format_encoders,
"json-api": Poison
config :plug, :mimes, %{
"application/vnd.api+json" => ["json-api"]
}

By default, jsonapi specs require the mime type to be:

application/vnd.api+json

Setting up CORS

Also, since our APIs will be consumed by a frontend app which will reside in some other domain, we’ll need to add CORS support for our backend app.

We’ll have to add cors_plug to our list of dependencies in mix.exs, which will look like this:

...
defp deps do
[{:phoenix, "~> 1.2.1"},
{:phoenix_pubsub, "~> 1.0"},
{:phoenix_ecto, "~> 3.0"},
{:postgrex, ">= 0.0.0"},
{:gettext, "~> 0.11"},
{:cowboy, "~> 1.0"},
{:cors_plug, "~> 1.2"}]
end
...

For now, the initial step to bootstrap our app is complete. Follow Infismash to know about how to proceed with the development.

JavaScript developer. Mostly interested in React/Redux stuffs!

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store