How to set up custom route for static assets

I want to serve a static asset named api.json located in the priv/static folder of my Phoenix (1.2) app. However, I don’t want to serve it at the root: localhost:4000/api.json, I want to serve it at localhost:4000/v1/api.json. How do I do this?

I tried this but it’s not working for me:

scope "/v1" do
  forward "/", Plug.Static, at: "/", from: :api, only: ~w(api.json)
end

have you tried adding the static plug with those options (after adjusting at:) to your endpoint?

Yes, when I change my endpoint’s Plug.Static to:

plug Plug.Static,
  at: "/v1/", from: :api, gzip: false,
  only: ~w(css fonts images js favicon.ico robots.txt api.json)

However, I only want the one asset, api.json to appear in the new route.

Have you tried having multiple Plug.Static?

plug Plug.Static,
  only: ~w(css fonts images js favicon.ico robots.txt)

plug Plug.Static,
  at: "/v1/", from: :api, gzip: false,
  only: ~w(api.json)

I’m not sure if that will work though, its just a quick guess based on the very little things that I do know about Plugs in general.

having multiple Plug.Statics should work. that’s what i was trying to say in my first post :slight_smile:

This does work, but I’d really like to have this logic in my router.

For example, it would be best if my user could hit an endpoint: /v1/api and have the api.json static asset returned. I’m struggling to figure out how to do this.

Either you have to use Plug.Static to halt the pipeline early when the file does exist, or you have to go through the full pipeline until you hit the view, from which you can return a static string, you can even load it at compile time from the file. But as I said, that needs to run through all plugs and therefore might be slightly slower.

I ended up using Plug.Conn.send_file/5 with a router to send the file contents from the endpoint I wanted.

Any news on this?