Current section
Files
Jump to
Current section
Files
lib/plumbapius/request.ex
defmodule Plumbapius.Request do
@moduledoc "Defines methods for validating requests by schema"
defmodule NotFoundError do
defexception [:method, :path]
@impl true
def message(exception) do
"request #{exception.method}: #{exception.path} was not found in schema"
end
end
defmodule UnknownContentTypeError do
defexception [:method, :path, :content_type]
@impl true
def message(exception) do
"request #{exception.method}: #{exception.path} " <>
"with content-type: #{exception.content_type} was not found. " <>
"Make sure you have correct `content-type` or `accept` headers in your request"
end
end
defmodule NoContentTypeError do
defexception [:method, :path]
@impl true
def message(exception) do
"request #{exception.method}: #{exception.path} has no content-type header"
end
end
alias Plumbapius.Request
@doc """
Validates request body according to a schema.
## Parameters
- request_schema: Request schema for validation.
- request_body: Request body to validate.
## Examples
iex> request_schema = Plumbapius.Request.Schema.new(%{
...> "method"=>"GET",
...> "path"=>"/users",
...> "content-type"=>"application/json",
...> "request"=>%{
...> "$schema" => "http://json-schema.org/draft-04/schema#",
...> "type" => "object",
...> "properties" => %{"msisdn" => %{"type" => "number"}},
...> "required" => ["msisdn"]
...> },
...> "responses"=>[]
...> })
iex> Plumbapius.Request.validate_body(request_schema, %{"msisdn" => 12345})
:ok
iex> Plumbapius.Request.validate_body(request_schema, %{"msisdn" => "12345"})
{:error, "#/msisdn: Type mismatch. Expected Number but got String."}
"""
@spec validate_body(Request.Schema.t(), map()) :: :ok | {:error, list()}
def validate_body(request_schema, request_body) do
case ExJsonSchema.Validator.validate(request_schema.body, request_body) do
:ok ->
:ok
{:error, errors} ->
{:error, Enum.map_join(errors, ", ", &format_schema_error/1)}
end
end
@spec match?(Request.Schema.t(), String.t(), String.t()) :: boolean()
def match?(_schema, _request_method, nil), do: false
def match?(schema, request_method, request_path) do
String.match?(request_path, schema.path) && schema.method == request_method
end
defp format_schema_error({description, json_path}) do
"#{json_path}: #{description}"
end
end