How to structure a phoenix project with a html and json api view?

Hello community!

Probably this question has already been answered here. I’ve also found similar questions (How to design app with JSON API and HTML interface?), but I don’t feel like I completely understand it.

I want to create a Phoenix app which has a JSON API and HTML interface. I wonder what’s a clean structure for my Phoenix app.

  • lib/example: In here is my domain and shared stuff like models and other things.
  • lib/example_web: Here the HTML interface lives.
  • lib/example_api: That’s where my API interface lives.

Currently I have a router.ex in my lib/example_web. Should I pull this into lib/example?

Thank you in advance!

You do not really need to separate html from api, because it is just web, and the router can do it.

You can have HTML interface responding at /, and the API at /api/

The router will use two pipelines, as mentionned in previous topic.

  pipeline :browser do
    plug :accepts, ["html"]
    plug :fetch_session
    plug :fetch_flash
    plug :protect_from_forgery
    plug :put_secure_browser_headers

  pipeline :api do
    plug :accepts, ["json"]

And scopes in the router will define which pipeline to take depending on url.

scope "/api", BlahWeb do
  pipe_through :api
  post "/sessions", SessionController, :create

scope "/", BlahWeb do
  pipe_through :browser
  get "/*path", PageController, :index

You can define multiple routes by method (get post patch put, delete), path, controller, action in each scope.

You can put HTML/API controllers in separate folders

controllers/ -> html controllers
controllers/api/ -> api controllers

You can do the same with views, and json api don’t use eex templates

This way, depending on the url, You will be routed to HTML or API.

API is also part of the web interface, just not responding at the same url, and usually speaking only json.

Both will communicate with your domain logic, where You find contexts, and schemas, not models :slight_smile: