I’m playing around with Phoenix currently and am working with essentially the outcome of a mix phx.new.
In the router.ex file I have:
pipeline :api do
plug :accepts, ["json"]
end
# Other scopes may use custom stacks.
scope "/api", HelloPhoenixWeb do
pipe_through :api
get "/show", PageController, :show
end
This works just fine.
I send in my request to /api/show and I see my JSON output.
I also see a header:
content-type →application/json; charset=utf-8
All good.
If I remove pipe_through :api and send in my request, I still see that same content-type header added. I’m guessing this is now being done by Poison?
Even so, what’s the point of pipe_through :api then in this case?
I get the reasoning for pipe_through generally, I’m just confused about what this particular pipeline is giving me.
I can see it does something, because changing to pipe through :browser does indeed change the response headers.
Performs content negotiation based on the available formats.
It receives a connection, a list of formats that the server is capable of rendering and then proceeds to perform content negotiation based on the request information. If the client accepts any of the given formats, the request proceeds.
It’s running the Conn through the plugs listed under pipeline :api. In this case, it’s checking the conn data structure has a content-type of json. I think it’s easier to understand when you add authentication. Here are two pipelines, one checks for basic authentication, the other for JWT.
pipeline :api do
plug :accepts, ["json", "json-api"]
plug BasicAuth, use_config: {:auth, :basic_auth}
plug JaSerializer.ContentTypeNegotiation
plug JaSerializer.Deserializer
end
pipeline :api_auth do
plug :accepts, ["json", "json-api"]
plug JaSerializer.ContentTypeNegotiation
plug JaSerializer.Deserializer
plug Guardian.Plug.VerifyHeader, realm: "Bearer"
plug Guardian.Plug.LoadResource
end
Each of these plugs takes some action on the Conn before it is routed to the controller.
Cheers both. I found some extra info in the docs that suggests that the outcome of piping through :api doesn’t do anything:
Conversely, if the request matches any of the routes defined by the resources/2 macro, the router will pipe it through the :api pipeline - which currently does nothing - before it dispatches further to the correct action of the HelloWeb.ReviewController.
I understand its value on more real world scenarios, and appreciate the examples.
It actually does: since the plug :accepts, ["json"] is inside the :api pipeline. If your browser/client does not accept the json response format, it will raise a Phoenix.NotAcceptableError according to the plug documentation:
This function raises Phoenix.NotAcceptableError, which is rendered with status 406, whenever the server cannot serve a response in any of the formats expected by the client.