Comments (16)
Hello @janfri !
You are right , right now the wasn't user stories to start the validate_payload epic and because this , this functionality only have mindmap and a basic sketch level implementation for spiking , but nothing released at this point.
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 :)))
from rack-app.
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
from rack-app.
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. :)
from rack-app.
okey, all the stuff from the team backlog went out,
today after work I start to work on your request @janfri : )))))
from rack-app.
Great news. :-)
from rack-app.
I split up your epic into two part.
one for the payload parsing based on content_type,
and one for the validating the parsed payload with a middleware.
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" ?
from rack-app.
split up your epic into two part.
one for the payload parsing based on content_type,
and one for the validating the parsed payload with a middleware.
Sounds reasonable.
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" ?
Maybe both?
- For simple cases methods like
parsed_payload
orparsed_payload_stream
would be comfortable. Examples are simple deserializers for JSON and XML. - For "strange" things maybe an IO object would be useful? (I'm not sure!) A use case could be to "parse" an uploded media file with mini_exiftool to get meta data for further work with the file.
Just my 2 cents. Maybe others have better ideas?
from rack-app.
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.
from rack-app.
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 HTTP 415
response? Or should payload
then have the unparsed content?
from rack-app.
The default behavior is the raw string .
So the already made specs won't break.
Anything that make pre requirement should go to validate_payload block , so it can be processed into documentation as well.
The payload method it self should not do any validation , and only serve as a data input in the controller.
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.
from rack-app.
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
Adam L.
from rack-app.
I'll be patient. ;-)
from rack-app.
You are such an amazing person, thank you very much! :)
from rack-app.
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).
The Payload now is configurable, and you can tell to accept one or more input format.
In this way, we don't break the rolling release backward compatibility, while the developers have a bigger range of control over what and how can be used in the application.
This also means, that the payload/parser block is optional for those who require and not forced to others.
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
from rack-app.
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.
from rack-app.
I Still think about the Validation. Is it really required ?
I Can't find any use case to drive this part now.
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.
And it is kind of idiomatic from the Rack and the middleware use mechanism.
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
from rack-app.
Related Issues (20)
- Website DNS routing problem HOT 2
- remove application configuration need during runtime
- RSpec warnings HOT 4
- [Question -- feature request?] Testing a rack-app with middlewares HOT 7
- Mounted application is not reloaded by Rack::Reloader HOT 4
- Error handler for mounted app HOT 3
- POST request without Content-Length header on WEBrick yields HTTP status code 411 HOT 4
- SPIKE: play around with Ruby 3 beta version.
- Rack::App::FileServer.serve_file gives Errno::EPERM when file served from a shared folder where multiple user keep files like the temp directory. HOT 7
- How to serve static assets with Rack::App? HOT 6
- params is empty {} when send form to post "/hello" HOT 5
- serializer block is not executed on http_status! responses HOT 2
- support json error response on validation HOT 1
- Website Squatted HOT 16
- Refine Hook Execution Scope to Match Defined Context HOT 2
- Make `request.params` behave similarly as the `params` method HOT 23
- Listing the middleware so I can see the order.
- Execute middleware stack for requests not matching any endpoint or mount point. HOT 15
- What is the best way to bundle views in an extension? HOT 6
- Outdated Sinatra fails to boot HOT 2
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from rack-app.