🚀 White Paper: Fauna Architectural Overview - A distributed document-relational database delivered as a cloud API.
Download free
Fauna logo
Product
Solutions
Pricing
Resources
Company
Log InContact usStart for free
Fauna logo
Pricing
Customers
Log InContact usStart for free
© 0 Fauna, Inc. All Rights Reserved.

Start for free

Sign up and claim your forever-free Fauna account
Sign up and get started

Table of Contents

Community Contribution
Fauna Elixir

A Practical Guide to Integrating Fauna with Elixir

Yuliya Petrunkina & Shadid Haque|Mar 13th, 2024|

Categories:

Elixir
The choice of a database plays an important role in the success of modern applications, and for Elixir enthusiasts, Fauna is an excellent choice that aligns seamlessly with the language's strengths. Elixir, built on the efficient Erlang virtual machine, thrives in managing concurrent processes, a trait that pairs exceptionally well with Fauna's serverless architecture. This synergy allows Elixir applications to effortlessly scale based on demand, catering to varying workloads.
The compatibility extends to Elixir's functional and fault-tolerant programming model, finding a natural match in Fauna's emphasis on strong consistency and ACID transactions. Whether your application spans multiple regions or faces a fault-prone environment, the Elixir-Fauna combination ensures data integrity amid distributed complexities. Developers benefit from the simplicity of Fauna, aligning with Elixir's developer-friendly syntax and tooling.
This practical guide will show you how to integrate Fauna into your Elixir app.

Create a new Elixir Project

To begin, ensure you have Elixir installed on your machine. If not, head to the Elixir website for installation instructions. Once installed, create a new Elixir project using Mix
mix new <name of your project>
Open your code in the code editor of your choice. Next, navigate to your project's mix.exs file and add the necessary dependencies - HTTPoison, Jason, and Dotenv. You can verify the versions on the Hex website. This is what my dependencies in my mix.exs file look like:
 defp deps do
   [
     {:httpoison, "~> 2.2"},
     {:jason, "~> 1.4"},
     {:dotenv, "~> 3.1"},
   ]
 end
Run mix deps.get in your terminal to fetch the dependencies.

Configure Fauna

Now, head to the Fauna dashboard and find or create your database.
Create New Database
Hover over the name of your database to see a manage keys icon.
Manage keys
From here you can create a Fauna database key. Create a new server key.
new server key
New server key
Next, create a .env file in your project and add the server key as an environment variable.
# .env 
FAUNA_KEY='<Your-Fauna-Secret-Key>'

Connecting to Fauna with Elixir

In the lib folder, create a faunadoo.ex file. Copy and paste the content provided below to create the Faunadoo module. This module will handle interactions with the Fauna database through an API call.
defmodule Faunadoo do
 alias HTTPoison

 def query(fql_expression, key) do
   url = "https://db.fauna.com/query/1"

   headers = [
     {"accept", "application/json, text/plain, */*"},
     {"authorization", "Bearer #{key}"},
     {"x-format", "simple"},
     {"x-typecheck", "false"}
   ]

   body = %{
     "query" => fql_expression,
     "arguments" => %{}
   }

   case HTTPoison.post(url, Jason.encode!(body), headers, hackney: [ssl: [{:versions, '[tlsv1.2]'}]]) do
     {:ok, %{status_code: 200, body: response_body}} ->
       {:ok, decode_response(response_body)}

     {:error, reason} ->
       {:error, "Failed to execute query: #{reason}"}
   end
 end

 defp decode_response(body) do
   {:ok, Jason.decode!(body)["data"]}
 end
end
Note, response from Fauna is formated into the right format in decode_response.

Writing the application code

Next, create an index.ex file in the lib folder. This file will contain all the functions related to running the todo app, basically all the CRUD operations required using Fauna queries.
The first step of setting up this file is to create a start function which will call our loop function and present the options we can access with our todo application. This should look something like this, but feel free to leave out or add your own options if you’re following along.
 def start(_type, _args) do
   IO.puts("Welcome to the Todo App!")

   loop("")
 end

 defp loop(_choice) do
   IO.puts("Choose an option:")
   IO.puts("1. Create Todo")
   IO.puts("2. View all Todos")
   IO.puts("3. View Todo by ID")
   IO.puts("4. View Todo by Content")
   IO.puts("5. View Todo by Status")
   IO.puts("6. Edit Todo")
   IO.puts("7. Delete Todo")
   IO.puts("8. Exit")

   input = IO.gets("Enter your choice: ") |> String.trim() |> String.to_integer()

   case input do
     1 -> create_todo()
     2 -> view_all_todos()
     3 -> view_todo_by_id()
     4 -> view_todo_by_content()
     5 -> view_todo_by_status()
     6 -> edit_todo()
     7 -> delete_todo()
     8 -> exit()
     _ -> IO.puts("Invalid choice. Please try again.")
   end

   loop(input)
 end
At this point we can start fleshing out the functions in our case. This is where we finally get to writing our Fauna queries. Below are a few of the functions, to view all the rest please check out the full code in the repository
 defp create_todo do
   IO.puts("Enter Todo content:")
   content = IO.gets("") |> String.trim()

   query = """
     Todo.create({"todo": "#{content}", "completed": false})
   """

   execute_query(query)
 end

 defp delete_todo do
   IO.puts("Enter Todo ID:")
   id = IO.gets("") |> String.trim()

   query = """
     let toDelete = Todo.byId(#{id})
     toDelete.delete()
   """

   execute_query(query)
 end

 defp execute_query(query) do
   key = System.get_env("FAUNA_KEY")

   case Faunadoo.query(query, key) do
     {:ok, data} ->
       IO.puts("Query result: #{Kernel.inspect(data)}")

     {:error, reason} ->
       IO.puts("Failed to execute query: #{reason}")
   end
 end
Note the Fauna key being passed into the execute_query function.
Now, at this point, you should be ready to test out your app! Run the following in your terminal:
mix run 
And that’s a wrap! We have created a simple terminal-based todo application using Elixir and Fauna. The Faunadoo module can be reused in any Elixir application to interact with the Fauna database and the queries in the index.ex file are a good starting place for any CRUD application.
Please make sure to check out the full code in the GitHub repository.

If you enjoyed our blog, and want to work on systems and challenges related to globally distributed systems, and serverless databases, Fauna is hiring!

Share this post

TWITTERLINKEDIN
‹︁ PreviousNext ›︁

Subscribe to Fauna's newsletter

Get latest blog posts, development tips & tricks, and latest learning material delivered right to your inbox.