diff --git a/lib/elixir_boilerplate/application.ex b/lib/elixir_boilerplate/application.ex index ecdfcde4..fd51d0d4 100644 --- a/lib/elixir_boilerplate/application.ex +++ b/lib/elixir_boilerplate/application.ex @@ -10,7 +10,8 @@ defmodule ElixirBoilerplate.Application do ElixirBoilerplateWeb.Telemetry, ElixirBoilerplate.Repo, {Phoenix.PubSub, [name: ElixirBoilerplate.PubSub, adapter: Phoenix.PubSub.PG2]}, - ElixirBoilerplateWeb.Endpoint + ElixirBoilerplateWeb.Endpoint, + {Absinthe.Subscription, ElixirBoilerplateWeb.Endpoint} ] opts = [strategy: :one_for_one, name: ElixirBoilerplate.Supervisor] diff --git a/lib/elixir_boilerplate_graphql/router.ex b/lib/elixir_boilerplate_graphql/router.ex deleted file mode 100644 index f4c5f76d..00000000 --- a/lib/elixir_boilerplate_graphql/router.ex +++ /dev/null @@ -1,27 +0,0 @@ -defmodule ElixirBoilerplateGraphQL.Router do - use Plug.Router - - defmodule GraphQL do - use Plug.Router - - plug(:match) - plug(:dispatch) - - forward("/", - to: Absinthe.Plug, - init_opts: [ - json_codec: Jason, - schema: ElixirBoilerplateGraphQL.Schema - ] - ) - end - - plug(ElixirBoilerplateGraphQL.Plugs.Context) - - plug(:match) - plug(:dispatch) - - forward("/graphql", to: GraphQL) - - match(_, do: conn) -end diff --git a/lib/elixir_boilerplate_graphql/schema.ex b/lib/elixir_boilerplate_graphql/schema.ex index 4979e89a..0451ea22 100644 --- a/lib/elixir_boilerplate_graphql/schema.ex +++ b/lib/elixir_boilerplate_graphql/schema.ex @@ -17,6 +17,7 @@ defmodule ElixirBoilerplateGraphQL.Schema do # first mutation. # # mutation do + # import_fields(:application_mutations) # end def context(context) do diff --git a/lib/elixir_boilerplate_web/endpoint.ex b/lib/elixir_boilerplate_web/endpoint.ex index edd116e2..cd031925 100644 --- a/lib/elixir_boilerplate_web/endpoint.ex +++ b/lib/elixir_boilerplate_web/endpoint.ex @@ -1,7 +1,10 @@ defmodule ElixirBoilerplateWeb.Endpoint do use Sentry.PlugCapture + use Phoenix.Endpoint, otp_app: :elixir_boilerplate + use Absinthe.Phoenix.Endpoint + alias Plug.Conn @plug_ssl Plug.SSL.init(rewrite_on: [:x_forwarded_proto]) @@ -49,10 +52,8 @@ defmodule ElixirBoilerplateWeb.Endpoint do plug(Plug.MethodOverride) plug(Plug.Head) - plug(ElixirBoilerplateWeb.Plugs.Security) + # plug(ElixirBoilerplateWeb.Plugs.Security) # plug(ElixirBoilerplateHealth.Router) - # plug(ElixirBoilerplateGraphQL.Router) - # plug(:halt_if_sent) plug(ElixirBoilerplateWeb.Router) @doc """ @@ -119,10 +120,4 @@ defmodule ElixirBoilerplateWeb.Endpoint do conn end end - - # Splitting routers in separate modules has a negative side effect: - # Phoenix.Router does not check the Plug.Conn state and tries to match the - # route even if it was already handled/sent by another router. - defp halt_if_sent(%{state: :sent, halted: false} = conn, _opts), do: halt(conn) - defp halt_if_sent(conn, _opts), do: conn end diff --git a/lib/elixir_boilerplate_web/router.ex b/lib/elixir_boilerplate_web/router.ex index 00e65c07..11aacf8e 100644 --- a/lib/elixir_boilerplate_web/router.ex +++ b/lib/elixir_boilerplate_web/router.ex @@ -2,7 +2,7 @@ defmodule ElixirBoilerplateWeb.Router do use Phoenix.Router pipeline :browser do - plug(:accepts, ["html", "json"]) + plug(:accepts, ~w[html json]) plug(:session) plug(:fetch_session) @@ -13,12 +13,31 @@ defmodule ElixirBoilerplateWeb.Router do plug(:put_root_layout, {ElixirBoilerplateWeb.Layouts, :root}) end + pipeline :api do + plug(:accepts, ~w[json]) + + plug(:session) + end + scope "/", ElixirBoilerplateWeb do - pipe_through(:browser) + pipe_through :browser get("/", PageController, :home) end + scope "/api" do + pipe_through :api + + forward("/graphql", Absinthe.Plug, schema: ElixirBoilerplateGraphQL.Schema) + + if Mix.env() == :dev do + forward("/graphiql", Absinthe.Plug.GraphiQL, + schema: ElixirBoilerplateGraphQL.Schema, + socket: ElixirBoilerplateWeb.Socket + ) + end + end + # The session will be stored in the cookie and signed, # this means its contents can be read but not tampered with. # Set :encryption_salt if you would also like to encrypt it. diff --git a/lib/elixir_boilerplate_web/socket.ex b/lib/elixir_boilerplate_web/socket.ex index 48838ab7..dd9ca576 100644 --- a/lib/elixir_boilerplate_web/socket.ex +++ b/lib/elixir_boilerplate_web/socket.ex @@ -1,6 +1,8 @@ defmodule ElixirBoilerplateWeb.Socket do use Phoenix.Socket + use Absinthe.Phoenix.Socket, schema: ElixirBoilerplateGraphQL.Schema + def connect(_params, socket) do {:ok, socket} end diff --git a/mix.exs b/mix.exs index dcea2954..766718a3 100644 --- a/mix.exs +++ b/mix.exs @@ -72,6 +72,7 @@ defmodule ElixirBoilerplate.Mixfile do # GraphQL {:absinthe, "~> 1.7"}, {:absinthe_plug, "~> 1.5"}, + {:absinthe_phoenix, "~> 2.0"}, {:dataloader, "~> 1.0"}, {:absinthe_error_payload, "~> 1.1"}, diff --git a/mix.lock b/mix.lock index edffc2a9..75ae2913 100644 --- a/mix.lock +++ b/mix.lock @@ -1,6 +1,7 @@ %{ "absinthe": {:hex, :absinthe, "1.7.1", "aca6f64994f0914628429ddbdfbf24212747b51780dae189dd98909da911757b", [:mix], [{:dataloader, "~> 1.0.0", [hex: :dataloader, repo: "hexpm", optional: true]}, {:decimal, "~> 1.0 or ~> 2.0", [hex: :decimal, repo: "hexpm", optional: true]}, {:nimble_parsec, "~> 1.2.2 or ~> 1.3.0", [hex: :nimble_parsec, repo: "hexpm", optional: false]}, {:telemetry, "~> 0.4 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "c0c4dbd93881fa3bfbad255608234b104b877c2a901850c1fe8c53b408a72a57"}, "absinthe_error_payload": {:hex, :absinthe_error_payload, "1.1.4", "502ff239148c8deaac028ddb600d6502d5be68d24fece0c93f4c3cf7e74c1a4d", [:make, :mix], [{:absinthe, "~> 1.3", [hex: :absinthe, repo: "hexpm", optional: false]}, {:ecto, "~> 3.1", [hex: :ecto, repo: "hexpm", optional: false]}], "hexpm", "9e262ef2fd4a2c644075e0cdde2573b1f713c0676ab905c8640eaa8a882b2aca"}, + "absinthe_phoenix": {:hex, :absinthe_phoenix, "2.0.2", "e607b438db900049b9b3760f8ecd0591017a46122fffed7057bf6989020992b5", [:mix], [{:absinthe, "~> 1.5", [hex: :absinthe, repo: "hexpm", optional: false]}, {:absinthe_plug, "~> 1.5", [hex: :absinthe_plug, repo: "hexpm", optional: false]}, {:decimal, "~> 1.0 or ~> 2.0", [hex: :decimal, repo: "hexpm", optional: false]}, {:phoenix, "~> 1.5", [hex: :phoenix, repo: "hexpm", optional: false]}, {:phoenix_html, "~> 2.13 or ~> 3.0", [hex: :phoenix_html, repo: "hexpm", optional: true]}, {:phoenix_pubsub, "~> 2.0", [hex: :phoenix_pubsub, repo: "hexpm", optional: false]}], "hexpm", "d36918925c380dc7d2ed7d039c9a3b4182ec36723f7417a68745ade5aab22f8d"}, "absinthe_plug": {:hex, :absinthe_plug, "1.5.8", "38d230641ba9dca8f72f1fed2dfc8abd53b3907d1996363da32434ab6ee5d6ab", [:mix], [{:absinthe, "~> 1.5", [hex: :absinthe, repo: "hexpm", optional: false]}, {:plug, "~> 1.4", [hex: :plug, repo: "hexpm", optional: false]}], "hexpm", "bbb04176647b735828861e7b2705465e53e2cf54ccf5a73ddd1ebd855f996e5a"}, "bunt": {:hex, :bunt, "0.2.1", "e2d4792f7bc0ced7583ab54922808919518d0e57ee162901a16a1b6664ef3b14", [:mix], [], "hexpm", "a330bfb4245239787b15005e66ae6845c9cd524a288f0d141c148b02603777a5"}, "castore": {:hex, :castore, "1.0.0", "c25cd0794c054ebe6908a86820c8b92b5695814479ec95eeff35192720b71eec", [:mix], [], "hexpm", "577d0e855983a97ca1dfa33cbb8a3b6ece6767397ffb4861514343b078fc284b"},