DEV Community

Cover image for Personal note: Build Elixir CRUD without Phoenix using MySQL and MongoDB
Burhanuddin Ahmed
Burhanuddin Ahmed

Posted on

Personal note: Build Elixir CRUD without Phoenix using MySQL and MongoDB

My personal note about learning Elixir.

Finding learning resources for Elixir is not as easy as JS learning resources. So I initiate this post to document my journey learning Elixir.

Basically I want to practice to create a create, read, list, update, and delete using MongoDB and MySQL.

Here, I will use Elixir without Phoenix framework, I want to know how Elixir work.

Make sure you have installed Elixir in your system.

To start a new project, use this command mix new <app-name> --sup

mix new todo_app --sup
Enter fullscreen mode Exit fullscreen mode

A --sup option can be given to generate an OTP application skeleton including a supervision tree. Normally an app is generated without a supervisor and without the app callback.

After initialize new project, it will create directory structure like this.

Dir structure

You will see Elixir extension with .ex and .exs. The ".ex" extension is used for Elixir source code files that are compiled into bytecode, while the ".exs" extension is used for Elixir script files that are interpreted directly.

Adding dependency

Go to /mix.exs, inside deps add the dependency.

 defp deps do
    [
      {:plug_cowboy, "~> 2.5"},
      {:jason, "~> 1.3"},
      {:mongodb_driver, "~> 0.8"},
      {:myxql, "~> 0.6.0"}
    ]
  end
Enter fullscreen mode Exit fullscreen mode

After adding the dependency, run mix deps.get.

plug_cowboy is a kind of Erlang web server, since we didn't use any framework like Phoenix, we can use it.
jason is a JSON parser and generator for Elixir.
mongo_driver for establishing connection with MongoDB, and myxql for connecting with MySQL.

Set up the dependency

After installing the dependencies, we need to set it up in our application.ex.

According to Elixir site

Applications are the idiomatic way to package software in Erlang/OTP. To get the idea, they are similar to the "library" concept common in other programming languages, but with some additional characteristics.

An application is a component implementing some specific functionality, with a standardized directory structure, configuration, and life cycle. Applications are loaded, started, and stopped. Each application also has its own environment, which provides a unified API for configuring each application.

Here we will define the entry point of our app. Let's head to lib/todo_app/application.ex

# lib/todo_app/application.ex

defmodule TodoApp.Application do
alias Mix.Tasks.Compile.App

  use Application

  @impl true
  def start(_type, _args) do
    children = [
      {
        Plug.Cowboy,
        scheme: :http,
        plug: TodoApp.Router,
        options: [port: Application.get_env(:todo_app, :port)]
      },
      {
        Mongo,
        name: :mongo,
        url: Application.get_env(:todo_app, :database_url),
      },
      {
        MyXQL,
        name: :myxql,
        hostname: Application.get_env(:todo_app, :mysql_host),
        username: Application.get_env(:todo_app, :mysql_username),
        password: Application.get_env(:todo_app, :mysql_password),
        database: Application.get_env(:todo_app, :mysql_database),
      }
    ]

    opts = [strategy: :one_for_one, name: TodoApp.Supervisor]
    Supervisor.start_link(children, opts)
  end
end
Enter fullscreen mode Exit fullscreen mode

We can see that we have setup for Cowboy, Mongo, and MySQL inside the application.ex. We can also see there are Application.get_env(:todo_app, :mysql_database), it means that we calling the value from an environment variable. Now let's define the env variable.

Env Variable

Go to config/, create config.exs and dev.env.exs.

Put this value into config.exs

# config/config.exs

import Config

# Import environment specific config. This must remain at the bottom
# of this file so it overrides the configuration defined above.
import_config "#{config_env()}.env.exs"
Enter fullscreen mode Exit fullscreen mode

The config file will import the code from dev.env.exs, if we use prod then we must have prod.env.exs.

In dev.env

# config/dev.env.exs

import Config

config :todo_app, port: 8081
config :todo_app, database_url: "mongodb://localhost:27017/sultanads"
config :todo_app, database: "db_demo"
config :todo_app, pool_size: 3
config :todo_app, :basic_auth, username: "abc", password: "abc"
config :todo_app, mysql_host: "localhost"
config :todo_app, mysql_username: "root"
config :todo_app, mysql_password: ""
config :todo_app, mysql_database: "dev_mdom"
Enter fullscreen mode Exit fullscreen mode

Read more about config here https://hexdocs.pm/elixir/main/Config.html

Next, define the router.

Router

Here in router, we will define the endpoint and add little CRUD logic.

https://github.com/burhanahmeed/elixir-mongodb-app/blob/master/lib/todo_app/router.ex

That's all, I can't explain much about it, but as a personal note it's enough for me to get started again one day.

Next, I will try with Phoenix, dockerize, and CI/CD.

Top comments (0)