Tutorial on Using Upstash Redis In Your Phoenix App and Deploying it on Fly.
1
Create a Elixir app with Phoenix--no-ecto
flag to disable
the datastore since we will only use Redis. See
Phoenix documentation for more details.
Navigate to the new directory by running
2
Add Redixmix.exs
file
(See Redix documentation):
mix deps.get
to install the new dependencies.
Next, we will add Redix to our app. In our case, we will add a single global Redix instance.
Open the application.ex
file and find the children
list in the start
function.
First, add a method to read the connection parameters from the REDIS_URL
environment variable.
We choose this name for the environment variable because Fly will create a secret with this name
when we launch the app with a Redis store. Use regex to extract the password, host and port
information from the Redis URL:
children
array.
(See Redix Documentation for more details)
socket_opts
parameter. If you wish to test
your app locally by creating an Upstash Redis yourself without Fly, you must define Redix
client without the socket_opts: [:inet6]
field.
3
Testing the Connectionlib/redix_demo_web/controllers/page_html/home.html.heex
file. Replace the content of
the file with:
lib/redix_demo_web/router.ex
file. In this file,
URL paths are defined with the scope
keyword. Update the scope
in the following way:
/status
path, which will be rendered with the
status
method we will define. The website will also render the home
page in /
and in /:text
. /:text
will essentially match any route
and the route will be available to our app as a parameter when rendering.
Finally, we will define the status page in
lib/redix_demo_web/controllers/page_controller.ex
. We will define a struct
Payload
and a private method render_home
. Then, we will define the home
page and the status page:
PING
request to our Redis server.
We are now ready to deploy the app on Fly!
4
Deploy on FlyREDIS_URL
environment variable in your environment, fly launch
command will show
an error when compiling the app but don’t worry. You can still continue with launching the app.
Fly will add this environment variable itself.
Fly will at some point ask if we want to tweak the settings of the app. Choose yes (y
):
REDIS_URL
from the Upstash Fly console
and add it as a secret with fly secrets set REDIS_URL=****
. Note that the REDIS_URL
will be in redis://default:****@fly-****.upstash.io:****
format.
Once the app is launched, deploy it with:
/status
page to see that
the redis connection is correctly done.
In the rest of our tutorial, we will work on caching the responses from an external api.
If you are only interested in how a Phoenix app with Redis can be deployed on Fly, you
may not need to read the rest of the tutorial.
5
Using Redix to Cache External API Responsesdef home(conn, %{"text" => text})
in the
lib/redix_demo_web/controllers/page_controller.ex
file. To see the final file, find the
page_controller.ex
file Upstash examples repository.
First, we need to define some private methods to handle the request logic. We start off
with a function to fetch the weather. The method gets the location string and replaces
the empty characters with %20
. Then it calls fetch_weather_from_cache
method we will
define. Depending on the result, it either returns the result from cache, or fetches the
result from the api.
fetch_weather_from_cache
method. This method will use
Redix to fetch the weather from the location. If it’s not found, we will return
{:error, :not_found}
. If it’s found, we will return after decoding it into a
map.
fetch_weather_from_api
method. This method
requests the weather information from the external API. If the request
is successfull, it also saves the result in the cache with the
cache_weather_response
method.
cache_weather_response
method, we simply store the weather
information in our Redis:
get_weather_info
and home
methods.
6
Re-deploying the App{:httpoison, "~> 1.5"}
dependency to mix.exs
file and run mix deps.get
.
Then, get an API key from WeatherAPI and set it as secret in
fly with:
fly deploy
in your directory to deploy the completed app!