Skip to content

Commit

Permalink
feat (Params): replace require and any_content_type options with …
Browse files Browse the repository at this point in the history
…`required`

Because it makes no sense to require two content-types as well as always parse, say, both json and form
  • Loading branch information
vladfaust committed Feb 26, 2019
1 parent a25ab42 commit cc10d71
Show file tree
Hide file tree
Showing 3 changed files with 31 additions and 43 deletions.
2 changes: 1 addition & 1 deletion spec/onyx-rest/action_spec.cr
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ class JSONAction
include Onyx::REST::Action

params do
json require: true, any_content_type: true do
json required: true do
type user, nilable: true do
type name : String
type email : String
Expand Down
36 changes: 15 additions & 21 deletions src/onyx-rest/endpoint/params/form.cr
Original file line number Diff line number Diff line change
Expand Up @@ -7,17 +7,9 @@ module Onyx::REST::Endpoint
#
# ## Options
#
# * `require` -- whether to require the form params for this endpoints
# (return `"400 Missing request body"` otherwise). If set to `true`,
# then the `params#form` getter will be non-nilable
# * `any_content_type` -- whether to try parsing the body regardless
# of the `"Content-Type"` header
#
# If both `require` and `any_content_type` options are `true`, then the endpoint
# will always try to parse the request body as a form and return 400 on error.
#
# If only `require` is `true` then the endpoint would expect the valid header,
# erroring otherwise.
# * `required` -- if set to `true`, will attempt to parse form params regardless
# of the `"Content-Type"` header and return a parameter error otherwise; the `params.form`
# getter becomes non-nilable
#
# ## Example
#
Expand Down Expand Up @@ -64,7 +56,7 @@ module Onyx::REST::Endpoint
# type id : Int32
# end
#
# form require: true, any_content_type: true do
# form required: true do
# type user do
# type email : String?
# type username : String?
Expand All @@ -78,7 +70,11 @@ module Onyx::REST::Endpoint
# end
# end
# ```
macro form(require _require = false, any_content_type = false, &block)
#
# ```shell
# > curl -X POST -d "user[email]=foo@example.com" http://localhost:5000/users/42
# ```
macro form(required = false, &block)
class FormBodyError < Onyx::REST::Error(PARAMS_ERROR_CODE)
def initialize(message : String, @path : Array(String))
super(message)
Expand Down Expand Up @@ -141,7 +137,7 @@ module Onyx::REST::Endpoint
{{yield.id}}
end

{% if _require %}
{% if required %}
getter! form : FormParams
{% else %}
getter form : FormParams?
Expand All @@ -152,19 +148,17 @@ module Onyx::REST::Endpoint

{% begin %}
begin
{% if any_content_type %}
if true
{% else %}
{% unless required %}
if request.headers["Content-Type"]?.try &.=~ /^application\/x-www-form-urlencoded/
{% end %}
if body = request.body
@form = FormParams.from_query(body.gets_to_end)
else
{% if !any_content_type || _require %}
raise FormBodyError.new("Missing request body", [] of String)
{% end %}
raise FormBodyError.new("Missing request body", [] of String)
end
end
{% unless required %}
end
{% end %}
rescue ex : ::HTTP::Params::Serializable::Error
raise FormBodyError.new("Form p" + ex.message.not_nil![1..-1], ex.path)
end
Expand Down
36 changes: 15 additions & 21 deletions src/onyx-rest/endpoint/params/json.cr
Original file line number Diff line number Diff line change
Expand Up @@ -8,17 +8,9 @@ module Onyx::REST::Endpoint
#
# ## Options
#
# * `require` -- whether to require the JSON params for this endpoints
# (return `"400 Missing request body"` otherwise). If set to `true`,
# then the `params#json` getter will be non-nilable
# * `any_content_type` -- whether to try parsing the body regardless
# of the `"Content-Type"` header
#
# If both `require` and `any_content_type` options are `true`, then the endpoint
# will always try to parse the request body as a JSON and return 400 on error.
#
# If only `require` is `true` then the endpoint would expect the valid header,
# erroring otherwise.
# * `required` -- if set to `true`, will attempt to parse JSON params regardless
# of the `"Content-Type"` header and return a parameter error otherwise; the `params.json`
# getter becomes non-nilable
#
# ## Example
#
Expand Down Expand Up @@ -65,7 +57,7 @@ module Onyx::REST::Endpoint
# type id : Int32
# end
#
# json require: true, any_content_type: true do
# json required: true do
# type user do
# type email : String?
# type username : String?
Expand All @@ -79,7 +71,11 @@ module Onyx::REST::Endpoint
# end
# end
# ```
macro json(require _require = false, any_content_type = false, &block)
#
# ```shell
# > curl -X POST -d '{"user":{"email":"foo@example.com"}}' http://localhost:5000/users/1
# ```
macro json(required = false, &block)
class JSONBodyError < Onyx::REST::Error(PARAMS_ERROR_CODE)
end

Expand Down Expand Up @@ -135,7 +131,7 @@ module Onyx::REST::Endpoint
{{yield.id}}
end

{% if _require %}
{% if required %}
getter! json : JSONBody
{% else %}
getter json : JSONBody?
Expand All @@ -146,19 +142,17 @@ module Onyx::REST::Endpoint

{% begin %}
begin
{% if any_content_type %}
if true
{% else %}
{% unless required %}
if request.headers["Content-Type"]?.try &.=~ /^application\/json/
{% end %}
if body = request.body
@json = JSONBody.from_json(body.gets_to_end)
else
{% if !any_content_type || _require %}
raise JSONBodyError.new("Missing request body")
{% end %}
raise JSONBodyError.new("Missing request body")
end
end
{% unless required %}
end
{% end %}
rescue ex : JSON::MappingError
raise JSONBodyError.new(ex.message.not_nil!.lines.first)
end
Expand Down

0 comments on commit cc10d71

Please sign in to comment.