- Production: https://rockelivery.gigalixirapp.com/
A food delivery backend made with Elixir and Phoenix.
Built-in:
Welcome
Users
GET
http://localhost:4000/api/usersGET
http://localhost:4000/api/users/:idPOST
http://localhost:4000/api/usersPUT
http://localhost:4000/api/users/:idDELETE
http://localhost:4000/api/users/:id
Items
- Install
asdf
, an extensible version manager for node, clojure, elixir and ruby:
# Install apt-get packages
$ sudo apt install curl git
# Clone asdf
$ git clone https://github.com/asdf-vm/asdf.git ~/.asdf --branch v0.8.0
# Add it to your path
$ echo '# asdf version manager' >> ~/.bashrc
$ echo '. $HOME/.asdf/asdf.sh' >> ~/.bashrc
$ echo '. $HOME/.asdf/completions/asdf.bash' >> ~/.bashrc
- Install
Erlang
,Elixir
andPhoenix
:
# Install apt-get packages
$ sudo apt-get -y install build-essential autoconf m4 libncurses5-dev \
libwxgtk3.0-gtk3-dev libgl1-mesa-dev libglu1-mesa-dev libpng-dev libssh-dev \
unixodbc-dev xsltproc fop libxml2-utils libncurses-dev openjdk-11-jdk
# Add plugins
$ asdf plugin-add erlang
$ asdf plugin-add elixir
# Install and set Elixir
$ asdf install elixir 1.11.3
$ asdf global elixir 1.11.3
# Install and set Erlang
$ asdf install erlang 23.2
$ asdf global erlang 23.2
# Verify installation
$ erl --version
$ elixir --version
# Install Phoenix
$ mix archive.install hex phx_new 1.5.8
Create a postgress docker container with:
$ docker run --name postgres -e POSTGRES_PASSWORD=postgres -p 5432:5432 -d postgres
# Create phoenix app without webpacker or html views
$ mix phx.new app_name --no-webpack --no-html
# Intall dependencies
$ mix deps.get
# Compile project
$ mix compile
# Generate linter config file
$ mix credo.gen.config
# Run linter
$ mix credo --strict
# Start Phoenix dev server on http://localhost:4000
$ mix phx.server
# Start your project as an Interactive Elixir session
$ iex -S mix
# List all configured routes
$ mix phx.routes
# Generate JWT secret
$ mix guardian.gen.secret
# Create and migrate database
$ mix ecto.setup
# Create a migration
$ mix ecto.gen.migration migration_name
# Run pending migrations
$ mix ecto.migrate
# Drop and migrate databases
$ mix ecto.reset
# Drop databases
$ mix ecto.drop
# Create databases
$ mix ecto.create
# Run tests
$ mix test
# Run tests w/ coverage report
$ mix test --cover
# Generate coverage report w/ excoveralls
$ mix coveralls
# Generate and save coverage report as html
$ mix coveralls.html
export SECRET_KEY_BASE="$(mix phx.gen.secret)"
export DATABASE_URL="postgresql://postgres:postgres@localhost:5432/rockelivery_dev"
MIX_ENV=prod mix release
MIX_ENV=prod APP_NAME=rockelivery PORT=4000 _build/prod/rel/rockelivery/bin/rockelivery start
APP_NAME=$(gigalixir create --name rockelivery)
gigalixir apps
git remote -v
echo "elixir_version=1.11.2" > elixir_buildpack.config
echo "erlang_version=23.2" >> elixir_buildpack.config
gigalixir pg:create --free
gigalixir pg
gigalixir config
# Deploy
git push gigalixir
gigalixir ps
gigalixir open
gigalixir logs -a rockelivery
# Database
gigalixir account:ssh_keys:add "$(cat ~/.ssh/id_rsa.pub)"
gigalixir ps:migrate
gigalixir ps:remote_console
System.cmd("whoami", [])
System.cmd("echo", ["hello"], into: IO.stream(:stdio, :line))
seed_script = Path.join(["#{:code.priv_dir(:rockelivery)}", "repo", "seeds.exs"])
Code.eval_file(seed_script)
Create a user:
> user_params = %{
name: "Luisito",
age: 40,
email: "[email protected]",
cpf: "12345678910",
address: "paper street 123",
cep: "01001000",
password: "password"
}
> Rockelivery.Users.Create.call(user_params)
Fetch users:
> Rockelivery.Repo.all(Rockelivery.User)
> Rockelivery.Repo.get(Rockelivery.User, "8623cdd8-7cad-43cc-953b-c30260a349f4")
> Rockelivery.Users.Get.by_id("8623cdd8-7cad-43cc-953b-c30260a349f4")
> Rockelivery.Users.Get.by_id("8623cdd8-7cad-43cc-953b-c30260a349f8")
> Rockelivery.Users.Get.by_id("8623cdd8")
> Rockelivery.Users.GetV2.by_id("8623cdd8-7cad-43cc-953b-c30260a349f4")
> Rockelivery.Users.GetV2.by_id("8623cdd8-7cad-43cc-953b-c30260a349f8")
> Rockelivery.Users.GetV2.by_id("8623cdd8")
> Rockelivery.Users.GetV3.by_id("8623cdd8-7cad-43cc-953b-c30260a349f4")
> Rockelivery.Users.GetV3.by_id("8623cdd8-7cad-43cc-953b-c30260a349f8")
> Rockelivery.Users.GetV3.by_id("8623cdd8")
Update a user:
> updated_user_params = %{
"id" => "9a519870-ff34-40ff-b24d-a0a387c8e73a",
"name" => "UPDATEDDDDDD",
"age" => 40,
"email" => "[email protected]",
"cpf" => "UPDATEDDDDD",
"address" => "UPDATEDDDDDD",
"cep" => "UPDATEDD"
}
> Rockelivery.Users.Update.call(updated_user_params)
Delete a user:
> Rockelivery.Users.Delete.call("8623cdd8-7cad-43cc-953b-c30260a349f4")
> Rockelivery.Users.GetV3.by_id("8623cdd8-7cad-43cc-953b-c30260a349f8")
> Rockelivery.Users.GetV3.by_id("8623cdd8")
Verify password:
> {:ok, %{password_hash: hash}} = Rockelivery.Users.Get.by_id("a2a60a12-1c03-4357-b370-c78ed28a9e38")
> Pbkdf2.verify_pass("password", hash)
true
> Pbkdf2.verify_pass("badddddd", hash)
false
> params = %{
"id" => "a2a60a12-1c03-4357-b370-c78ed28a9e38",
"password" => "password"
}
> RockeliveryWeb.Auth.Guardian.authenticate(params)
> bad_params = %{
"id" => "a2a60a12-1c03-4357-b370-c78ed28a9e38",
"password" => "badddddd"
}
> RockeliveryWeb.Auth.Guardian.authenticate(bad_params)
Orders report:
> Rockelivery.Orders.Report.create()
Tesla HTTP client:
> Tesla.get("https://api.github.com/users/danilo-vieira/repos")
> Tesla.get("https://viacep.com.br/ws/01001000/json/")
> Tesla.get("https://viacep.com.br/ws/01001-000/json/")
> Tesla.get("https://viacep.com.br/ws/00000000/json/")
> Tesla.get("https://viacep.com.br/ws/123/json/")
ViaCep client:
> ViaCEP.Client.get_cep_info("01001000")
> ViaCEP.Client.get_cep_info("01001-000")
> ViaCEP.Client.get_cep_info("00000000")
> ViaCEP.Client.get_cep_info("123")
Stack server:
> {:ok, pid} = Rockelivery.Stack.start_link()
> Rockelivery.Stack.push(pid, :world)
> Rockelivery.Stack.push_async(pid, :world)
> Rockelivery.Stack.pop(pid)
> Rockelivery.Stack.pop_async(pid)
Enum:
> Enum.chunk_every([1, 2, 3, 4, 5, 6, 7, 8], 3) |> Enum.flat_map(fn [_head | tails] -> tails end)
- https://github.com/phoenixframework/phoenix
- https://github.com/rrrene/credo
- https://github.com/avdi/dotenv_elixir
- https://github.com/elixir-plug/plug
- https://github.com/riverrun/pbkdf2_elixir
- https://github.com/elixir-plug/plug
- https://github.com/parroty/excoveralls
- https://github.com/thoughtbot/ex_machina
- https://github.com/teamon/tesla
- https://github.com/PSPDFKit-labs/bypass
- https://github.com/dashbitco/mox
- https://github.com/ueberauth/guardian
- https://elixir-lang.org/crash-course.html
- https://elixir-lang.org/getting-started/sigils.html
- https://elixir-lang.org/getting-started/mix-otp/genserver.html
- https://hexdocs.pm/elixir/master/typespecs.html
- https://hexdocs.pm/elixir/master/GenServer.html
- https://hexdocs.pm/elixir/master/Supervisor.html
- https://hexdocs.pm/elixir/System.html#cmd/3
- https://hexdocs.pm/phoenix/installation.html#content
- https://github.com/inotify-tools/inotify-tools/wiki
- https://hexdocs.pm/phoenix/deployment.html
- https://hexdocs.pm/plug/readme.html
- https://hexdocs.pm/ecto/Ecto.Changeset.html
- https://hexdocs.pm/ecto/Ecto.Schema.html
- https://hexdocs.pm/ecto/Ecto.Repo.html#c:stream/2
- https://hexdocs.pm/pbkdf2_elixir/Pbkdf2.html
- https://hexdocs.pm/plug/readme.html
- https://hexdocs.pm/iex/master/IEx.html#pry/0
- https://hexdocs.pm/ecto/2.2.11/associations.html#content
- https://hexdocs.pm/tesla/readme.html
- https://hexdocs.pm/bypass/Bypass.html
- https://hexdocs.pm/mox/Mox.html
- https://github.com/actions
- https://github.com/actions/starter-workflows
- https://github.com/actions/starter-workflows/blob/fc65e636f2a8e8dcc0048090ca715cd6b5d76e40/ci/elixir.yml
- https://github.com/mijailr/actions_sample/blob/master/.github/workflows/elixir.yml
- https://docs.github.com/en/actions/learn-github-actions/migrating-from-gitlab-cicd-to-github-actions#databases-and-service-containers
- https://docs.github.com/en/actions/guides
- https://docs.github.com/en/actions/managing-workflow-runs
- https://docs.github.com/en/actions/learn-github-actions
- https://docs.github.com/en/actions
- https://docs.codecov.io/docs
- https://hexdocs.pm/mix/master/Mix.Tasks.Release.html
- https://elixir-lang.org/getting-started/mix-otp/config-and-releases.html#releases
- https://gigalixir.readthedocs.io/en/latest/getting-started-guide.html
- https://gigalixir.readthedocs.io/en/latest/modify-app/releases.html#modifying-existing-app-with-elixir-releases
- https://gigalixir.readthedocs.io/en/latest/tiers-pricing.html
- https://gigalixir.readthedocs.io/en/latest/deploy.html?highlight=staging#how-to-set-up-a-staging-environment
- https://gigalixir.readthedocs.io/en/latest/database.html?highlight=seeds#how-to-run-seeds
- https://github.com/marketplace/actions/gigalixir-action
- https://stackoverflow.com/questions/201323/how-to-validate-an-email-address-using-a-regular-expression
- https://stackoverflow.com/questions/31990134/how-to-convert-map-keys-from-strings-to-atoms-in-elixir
- https://stackoverflow.com/questions/16506351/why-use-a-callback-instead-of-a-normal-function-call
- https://stackoverflow.com/questions/9560815/how-to-get-erlangs-release-version-number-from-a-shell
- https://stackoverflow.com/questions/22594988/run-shell-commands-in-elixir
- https://www.tutorialspoint.com/elixir/elixir_lists_and_tuples.htm
- https://elixirforum.com/c/phoenix-forum
- https://www.formget.com/regular-expression-for-email/
- https://github.com/parroty/excoveralls/blob/master/.github/workflows/tests.yml
- https://medium.com/@diamondgfx/debugging-phoenix-with-iex-pry-5417256e1d11
- https://elixirschool.com/en/lessons/ecto/associations/
- https://viacep.com.br/
- https://inquisitivedeveloper.com/lwm-elixir-18/
- https://www.bestrandoms.com/random-address-in-br
- https://dashbit.co/blog/mocks-and-explicit-contracts
- https://cloudless.studio/model-callbacks-in-phoenix-ecto-and-rails
- https://jwt.io/