diff --git a/CHANGELOG.md b/CHANGELOG.md index 4cdbc16ac2..e5cfff6507 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -29,6 +29,13 @@ This release introduces deprecation warnings for several features that have been * The `config` variable is no longer available in `Phoenix.Endpoint`. In the past, it was possible to read your endpoint configuration at compile-time via an injected variable named `config`, which is no longer supported. Use `Application.compile_env/3` instead, which is tracked by the Elixir compiler and lead to a better developer experience. This may also lead to errors on application boot if you were previously incorrectly setting compile time config at runtime. +## 1.9.0 + +This release requires Plug v1.21+. + +### Enhancements +- [Router] Add the `query` macro for routing HTTP QUERY (RFC 10008) requests ([#6737](https://github.com/phoenixframework/phoenix/pull/6737)) + ## 1.8.8 (2026-06-10) ### Enhancements diff --git a/guides/routing.md b/guides/routing.md index b7efc0b24f..3486321253 100644 --- a/guides/routing.md +++ b/guides/routing.md @@ -56,7 +56,7 @@ Inside the scope block, however, we have our first actual route: get "/", PageController, :home ``` -`get` is a Phoenix macro that corresponds to the HTTP verb GET. Similar macros exist for other HTTP verbs, including POST, PUT, PATCH, DELETE, OPTIONS, CONNECT, TRACE, and HEAD. +`get` is a Phoenix macro that corresponds to the HTTP verb GET. Similar macros exist for other HTTP verbs, including QUERY, POST, PUT, PATCH, DELETE, OPTIONS, CONNECT, TRACE, and HEAD. > #### Why the macros? {: .info} > diff --git a/lib/phoenix/router.ex b/lib/phoenix/router.ex index e63357bb5b..ae7487c781 100644 --- a/lib/phoenix/router.ex +++ b/lib/phoenix/router.ex @@ -282,7 +282,7 @@ defmodule Phoenix.Router do alias Phoenix.Router.{Resource, Scope, Route, Helpers} - @http_methods [:get, :post, :put, :patch, :delete, :options, :connect, :trace, :head] + @http_methods [:get, :query, :post, :put, :patch, :delete, :options, :connect, :trace, :head] @doc false defmacro __using__(opts) do diff --git a/lib/phoenix/test/conn_test.ex b/lib/phoenix/test/conn_test.ex index 9def147398..466c9d4298 100644 --- a/lib/phoenix/test/conn_test.ex +++ b/lib/phoenix/test/conn_test.ex @@ -154,7 +154,7 @@ defmodule Phoenix.ConnTest do |> Conn.put_private(:phoenix_recycled, true) end - @http_methods [:get, :post, :put, :patch, :delete, :options, :connect, :trace, :head] + @http_methods [:get, :query, :post, :put, :patch, :delete, :options, :connect, :trace, :head] for method <- @http_methods do @doc """ diff --git a/mix.exs b/mix.exs index adfa1435ab..d1be1cf152 100644 --- a/mix.exs +++ b/mix.exs @@ -79,7 +79,7 @@ defmodule Phoenix.MixProject do defp deps do [ - {:plug, "~> 1.14"}, + {:plug, "~> 1.21"}, {:plug_crypto, "~> 1.2 or ~> 2.0"}, {:telemetry, "~> 0.4 or ~> 1.0"}, {:phoenix_pubsub, "~> 2.1"}, diff --git a/test/phoenix/router/routing_test.exs b/test/phoenix/router/routing_test.exs index 5142294df5..05821a7278 100644 --- a/test/phoenix/router/routing_test.exs +++ b/test/phoenix/router/routing_test.exs @@ -17,6 +17,7 @@ defmodule Phoenix.Router.RoutingTest do def options(conn, _params), do: text(conn, "users options") def connect(conn, _params), do: text(conn, "users connect") def trace(conn, _params), do: text(conn, "users trace") + def query(conn, _params), do: text(conn, "users query") def not_found(conn, _params), do: text(put_status(conn, :not_found), "not found") def image(conn, _params), do: text(conn, conn.params["path"] || "show files") def move(conn, _params), do: text(conn, "users move") @@ -56,6 +57,7 @@ defmodule Phoenix.Router.RoutingTest do trace("/trace", UserController, :trace) options "/options", UserController, :options connect "/connect", UserController, :connect + query "/query", UserController, :query match :move, "/move", UserController, :move match :*, "/any", UserController, :any @@ -185,6 +187,12 @@ defmodule Phoenix.Router.RoutingTest do assert conn.resp_body == "users trace" end + test "query to custom action" do + conn = call(Router, :query, "/query") + assert conn.status == 200 + assert conn.resp_body == "users query" + end + test "splat arg with preceding named parameter to files/:user_name/*path" do conn = call(Router, :get, "/files/elixir/Users/home/file.txt") assert conn.status == 200