Building an Action
Learn about how to generate boilerplate HTML and how to set routes in phoenix.
We'll cover the following...
Building the Phoenix application
The first thing we’ll need is a simple way to list all the menu items we have in our system so we can then take further action. If you aren’t familiar with server-side rendering in Phoenix, don’t worry. We’ll cover everything we need to know here. In order to avoid writing a ton of HTML boilerplate, we’ll use one of the Phoenix generators, and then replace the generated controller contents as needed.
mix phx.gen.html --no-context --no-schema Menu Item itemsrm test/plate_slate_web/controllers/item_controller_test.exs
The first command generates some boilerplate HTML for us, and the second removes a test case we don’t need. Up next is our router. We’ll use the :browser
pipeline that’s unused so far by creating an /admin
scope inside which we’ll set up our controller:
scope "/admin", PlateSlateWeb dopipe_through :browserresources "/items", ItemControllerend
Routes configuration
We can confirm that our router is properly set up by using the handy mix phx.routes
command:
mix phx.routes* /api Absinthe.Plug [schema: PlateSlateWeb.Schema]* /graphiql Absinthe.Plug.GraphiQL [...]item_path GET /admin/items PlateSlateWeb.ItemController :indexitem_path GET /admin/items/:id/edit PlateSlateWeb.ItemController :edititem_path GET /admin/items/new PlateSlateWeb.ItemController :newitem_path GET /admin/items/:id PlateSlateWeb.ItemController :showitem_path POST /admin/items PlateSlateWeb.ItemController :createitem_path PATCH /admin/items/:id PlateSlateWeb.ItemController :updatePUT /admin/items/:id PlateSlateWeb.ItemController :updateitem_path DELETE /admin/items/:id PlateSlateWeb.ItemController :delete
We can now turn our attention to the controller, where we’ll replace its existing contents entirely with the following:
defmodule PlateSlateWeb.ItemController douse PlateSlateWeb, :controlleruse Absinthe.Phoenix.Controller,schema: PlateSlateWeb.Schemaend
Now for the fun part. The Absinthe.Phoenix.Controller
gives us a way to associate a GraphQL query with a controller action. We can use the data that was looked up from that query in our controller. We won’t replace the controller actions, but rather augment them by utilizing all the lookup abilities we’ve already written. This lets our controller focus on just managing the HTTP connection. Let’s start with something basic:
@graphql """{menu_items {name}}"""def index(conn, result) doresult |> IO.inspectrender(conn, "index.html", items: result.data["menu_items"] || [])end
Let’s break this down. At the top of this snippet is a @graphql
module attribute on which we’re putting a string with a GraphQL query. Beneath that there’s a relatively ordinary-looking Phoenix controller callback index/2
. This controller gets the HTTP conn and some params. Then, it renders an index.html
.
At a high level, the controller action acts ...