This pull request is required to make Raxx more friendly to HTTP/2. This has meant the deprecation of certain features around transfer-encoding and old solutions on streaming.
The result is raxx applications will implement several callbacks, rather than a single handle_request.
Given a chat application with three endpoints, each can be a simple Raxx.App
For the home_page.ex a simple Request with no body is reacted too with a single response with the body generated all at once.
defmodule HomePage do
use Raxx.App
require EEx
EEx.function_from_file(:defp, :home_page, Path.join(__DIR__, "./templates/home_page.html.eex"), [])
def handle_headers(request, config) do
body = home_page()
Raxx.Response.new(:ok, [{"content-type", "text/html"}], body)
end
end
For publish_message.ex a post endpoint where the body is read into a complete buffer
defmodule PublishMessage do
use Raxx.App
alias WaterCooler.ChatRoom
require ChatRoom
def handle_headers(request, config) do
{[], {:reading, ""}}
end
def handle_fragment(fragment, {:reading, buffer}) do
{[], {:reading, buffer <> fragment}}
end
def handle_trailers([], {:reading, body}) do
{:ok, %{message: message}} = parse_publish_form(body)
{:ok, _} = ChatRoom.publish(message)
response = Raxx.Response.new(303, [{"location", "/"}], false)
end
def parse_publish_form(raw) do
%{"message" => message} = URI.decode_www_form(raw) |> URI.decode_query
{:ok, %{message: message}}
end
end
A subscribe_to_messages.ex endpoint where the server can push information.
defmodule SubscribeToMessages do
use Raxx.App
alias WaterCooler.ChatRoom
require ChatRoom
def handle_headers(request, config) do
{:ok, _} = ChatRoom.join()
response = Raxx.Response.new(:ok, [{"content-type", "text/event-stream"}], true)
response
end
end
Questions
is Raxx.App a good name what about Raxx.endpoint or Raxx.Action
should there be a Raxx.Unary (Unary term taken from GRPC) that buffers a request and send a complete response, allows getting back to the simple handle_request. Would allow the publish message endpoint to be rewritten as
def PublishMessage do
use Raxx.Unary, max_buffer: 1_000_000 # limit to body read from socket
def handle_request(request, config) do
{:ok, %{message: message}} = parse_publish_form(request.body)
{:ok, _} = ChatRoom.publish(message)
Raxx.Response.new(303, [{"location", "/"}], false)
end
end
This pull request is required to make Raxx more friendly to HTTP/2. This has meant the deprecation of certain features around transfer-encoding and old solutions on streaming. The result is raxx applications will implement several callbacks, rather than a single
handle_request
.Given a chat application with three endpoints, each can be a simple Raxx.App
For the
home_page.ex
a simple Request with no body is reacted too with a single response with the body generated all at once.For
publish_message.ex
a post endpoint where the body is read into a complete bufferA
subscribe_to_messages.ex
endpoint where the server can push information.Questions
Raxx.App
a good name what aboutRaxx.endpoint
orRaxx.Action
handle_request
. Would allow the publish message endpoint to be rewritten as