Hello, I'm quite new in the elixir world. I want to write some notes so it will help me for later if I want to try this again. This guide will not really details. I will assume that you familiar enough to know about Elixir, Phoenix, Absinthe or ExAws itself. I will assume you are also familiar with AWS especially S3.
Alternative library that you might be interested: https://github.com/stavro/arc
Preparation
- Make sure you are already install Elixir in your computer/PC.
- Generate new Phoenix Project. (If you are already have the Phoenix Project, you can skip this step).
mix archive.install hex phx_new
mix phx.new elixir_exploration
Note:
- Phoenix Installation Documentation
- Phoenix Generate Project
- Make sure you are already have PostgreSQL, if you not want to use database, please refer to note number 2, how to generate without
Ecto
which handle the database side.
- Add Absinthe and ExAWS as Dependencies. Add these to
mix.exs
defp deps do
[
... # rest of dependencies, please not input this too
{:absinthe, "~> 1.6"},
{:absinthe_plug, "~> 1.5"},
{:absinthe_phoenix, "~> 2.0"},
{:ex_aws, "~> 2.2"},
{:ex_aws_s3, "~> 2.0"},
{:poison, "~> 3.0"},
{:hackney, "~> 1.9"},
{:sweet_xml, "~> 0.6"},
]
end
Download all deps, use
mix deps.get
Prepare your AWS S3. :) Please read more in their documentation. https://aws.amazon.com/s3/
Prepare your account, we will use
AWS_ACCESS_KEY_ID
andAWS_SECRET_ACCESS_KEY
. Please visit here for more information aboutExAWS
: https://github.com/ex-aws/ex_aws
Let's Code
My code structure will be like this:
- root
-- elixir_exploration
-- elixir_exploration_web
--- resolvers # store all GraphQL resolvers
--- schema # store all GraphQL schemas
-- schema.ex # store all GraphQL query/mutations
- I will code at GraphQL side first (Absinthe). Please setup the Absinthe first.
You can refer this guide: https://hexdocs.pm/absinthe/plug-phoenix.html
I really love most of popular library, they bring us a nice guide. :)
- Write the resolver, I will put in
elixir_exploration_web/resolvers/uploads.ex
defmodule ElixirExplorationWeb.Resolvers.Uploads do
alias ExAws.S3
def upload_to_aws(_, %{input: input}, _) do
IO.inspect(input.file)
request = input.file.path
|> S3.Upload.stream_file()
# take care the filename, you should validate this
|> S3.upload("upload-test-berv", "uploads/#{input.file.filename}")
|> ExAws.request()
case request do
{:ok, _} -> {:ok, "Success"}
{:error, _} -> {:error, "Please try again"}
end
end
end
Don't forget to update the bucket name. In that example, I use upload-test-berv
as the bucket name. I use uploads/#{input.file.filename}
as the target file location.
- Write the schema, I will put in
elixir_exploration_web/schema/upload_types.ex
defmodule ElixirExplorationWeb.Schema.UploadTypes do
use Absinthe.Schema.Notation
alias ElixirExplorationWeb.Resolvers
import_types(Absinthe.Plug.Types)
object :upload_file do
@desc """
Upload a file
"""
field :upload_file, :string do
arg(:input, non_null(:file_input))
resolve(&Resolvers.Uploads.upload_to_aws/3)
end
end
input_object :file_input do
field :file, non_null(:upload)
end
end
- Import those files into
elixir_exploration_web/schema.ex
defmodule ElixirExplorationWeb.Schema do
use Absinthe.Schema
alias ElixirExplorationWeb.Schema
import_types(Schema.UploadTypes)
query do
end
mutation do
import_fields(:upload_file)
end
end
- Update config, I want to setup the default region. Currently I update to
config/config.exs
, but feel free to add different approach for different env.
config :ex_aws,
region: {:system, "AWS_DEFAULT_REGION"}
- Write the
env.sh
, this for setup our environment variable in our system.
export AWS_ACCESS_KEY_ID=<your_access_key_id>
export AWS_SECRET_ACCESS_KEY=<your_secret_access_key>
export AWS_DEFAULT_REGION=ap-southeast-1
Feel free to use another region. :)
Apply the environment, you can use
source env.sh
.Run your Phoenix Server.
mix phx.server
Test your API. Because my API locate at
localhost:4000/api/graphql
, so I will use that. If you set another path, please update it from my script below.
curl -X POST -F query="mutation { uploadFile(input: {file: \"my_data\"})}" -F my_data=@mix.exs -H "Accept:application/json" localhost:4000/api/graphql
- Check your S3
My Repo
You also can visit my repositories. I will write more in there if I have any updates.
berviantoleo / elixir-exploration
Explore more about elixir
ElixirExploration
To start your Phoenix server:
- Install dependencies with
mix deps.get
- Create and migrate your database with
mix ecto.setup
- Start Phoenix endpoint with
mix phx.server
Now you can visit localhost:4000
from your browser.
Ready to run in production? Please check our deployment guides.
Blog Post
Part of this post
Learn more
- Official website: https://www.phoenixframework.org/
- Guides: https://hexdocs.pm/phoenix/overview.html
- Docs: https://hexdocs.pm/phoenix
- Forum: https://elixirforum.com/c/phoenix-forum
- Source: https://github.com/phoenixframework/phoenix
Congrats
Yey! Congrats! You've implemented file upload and upload the file to AWS S3. In the next section, maybe I will write to show the result after you upload the file. The approach I will use:
- Use database as the listing
- Call AWS S3 API Directly to get the list
I hope I will write in the next month and write each approach in different article.
Thank you. :)
Top comments (0)