-
Notifications
You must be signed in to change notification settings - Fork 21
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Parsing form data #10
Comments
Hello @janfri ! We thinking about the following singleton method .payload do
unserialize do
on "request content type here" do |payload|
CustomUnserialize.parse(payload)
end
on "application/json" do |payload|
JSON.parse(payload)
end
end
validate do
it_is_a Array, of: Hash do |element|
element.has_a_key "foo", which_is_a: String
end
end
end
get "/baz" do
payload #> [{"Foo" => "bar"}]
end But it's an early concept, and we still in the process gathering user stories from our production use cases . It would be great if you could provide example scenarios to us if you don't mind the time :))) |
Payload may be complex so it could become epic indeed. ;-) My current case is a very simple API in REST style. I need only one simple param message of type string with size between 1 and 30. My current solution is something like: require 'rack/app'
require 'json'
class App < Rack::App
def form_data
case request.media_type
when 'application/json'
request.body.rewind
JSON.parse(request.body.read)
else
request.POST
end
end
def size_in_range? obj, range
(obj.respond_to? :size) && (range === obj.size)
end
desc 'create a new event'
post '/events' do
msg = form_data['message']
if size_in_range? msg, 1..30
# create event
'New event created'
else
# do error handling
response.status = 400
'no valid message given'
end
end
end
run App So I can send the data URL-encoded, FORM-DATA-encoded or JSON-encoded: $ curl -X POST -d message=foo http://localhost:9292/events
New event created
$ curl -X POST -F message=foo http://localhost:9292/events
New event created
$ curl -H "Content-Type: application/json" -X POST -d '{"message": "foo"}' http://localhost:9292/events
New event created |
Awesome ! I think we should provide something that doesn't include custom dsl but something that is easy to understand and generic. I start working on your request, as soon as the formats epic gets done. :) |
okey, all the stuff from the team backlog went out, |
Great news. :-) |
I split up your epic into two part. one for the payload parsing based on content_type, For the first, what do you think, should it be go under the "payload" and "payload_stream" method as a dynamic object that is behave based on the content type unserialization, or there should be a new method, something like "parsed_payload" and "parsed_payload_stream" ? |
Sounds reasonable.
Maybe both?
Just my 2 cents. Maybe others have better ideas? |
I talked about this with @BlasiusVonSzerencsi who use actively in production, and he mentioned, that it would be awesome if the :payload method would be dynamic based on the content_type, and there would be a :raw_payload for those, who want work explicitly with the string content of the payload. |
Accepted. What should be the reaction to a request with an unsupported content_type? Should there be an automatic |
The default behavior is the raw string . That's the current direction if you like it. :))) I already started to design the validate_payload method that almost alike with the validated_params syntax. |
Hello @janfri, sorry for not taking care of your issue, my daughter born and life was busy with this in these days. <3 I soon start to work on your request as soon as I can. Best regards |
I'll be patient. ;-) |
You are such an amazing person, thank you very much! :) |
Hy @janfri ! Update in the implementation. Yesterday, I talked about your feature request with my friends, and they suggested, that I should implement this as a middleware (which was in the original plan to). Any opinion? require 'rack/app'
class App < Rack::App
payload do
parser do
accept :json, :www_form_urlencoded
on "x-custom-content-type" do |io|
MyCustomContentTypeParser.load(io)
end
end
end
desc 'health check endpoint'
get '/' do
payload #> is an object based on the content type and the defined custom parsers
end
end |
rack-app 5.7.0 built to pkg/rack-app-5.7.0.gem.
Tagged v5.7.0.
Pushed git commits and tags.
Pushed rack-app 5.7.0 to rubygems.org. |
I Still think about the Validation. Is it really required ? For Example, all the use case I found, were using a custom Error handler block + a class that validate the payload based on restful params. class App < Rack::App
get "/" do
CustomValidation.new(payload)
payload
end
error CustomValidationError do |ex|
response.status = 400
response.write(ex.message)
finish!
end
end
|
Is there a nice way to get parsed values of form data? I can do
but
request.POST
seems not to be very rack-app-ish. In standard rack the parsed form data is merged in params but I think a different method likeparsed_form_data
would be a better solution.It would also be nice to have validations for form data, something like
Did I miss something or is such functionality not (yet) implemented?
The text was updated successfully, but these errors were encountered: