How do I set a Plug path containing a literal colon?

How do I set a Plug path containing a literal colon?

Working on a project that mirrors 1:1 the paths of the Google Datastore API.
The API to mirror contains things like: reference

POST /v1/projects/{projectId}:lookup

(So no choice/ option to drop it.)

I tried the following:

post "/v1/projects/:project_id\\:lookup" do
  ...
end

Plug parses the : as a second variable and escaping seems to not prevent this behavior.

Is there any straightforward way to get the literal colon in the path?
If not the best approach I can think of is matching the whole segment as variable and then manually matching.

1 Like

Seems like you cannot. Using Plug globbing (Plug.Router docs here) however, you can cobble together a hack-ish solution. This worked for me on a brand new Plug project with a router:

  get "/v1/projects/*project_id" do
    # because you get a list with a single element
    id = hd(project_id)

    if String.ends_with?(id, ":lookup") do
      id = String.trim_trailing(id, ":lookup")
      send_resp(conn, 200, "looking up project #{id}")
    else
      send_resp(conn, 200, "something else is happening")
    end
  end

Basically match everything after /v1/projects/ and split it up yourself and then branch and execute different coding paths depending on result. A bit ugly but it works. It’s also quite adaptable to a Phoenix Controller if that’s how you are writing the project.

1 Like