Skip to content

Instantly share code, notes, and snippets.

@krainboltgreene
Last active August 29, 2015 14:07
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save krainboltgreene/fcb647a3e6285793267f to your computer and use it in GitHub Desktop.
Save krainboltgreene/fcb647a3e6285793267f to your computer and use it in GitHub Desktop.
require "webstack"
require "webstack-throttle"
require "webstack-protection"
require "webstack-tempfile_manager"
require "webstack-deserializer"
require "webstack-dispatcher"
require "webstack-content_length_setter"
require "webstack-content_type_setter"
require "webstack-accept_setter"
require "webstack-serializer"
# Each cycle calls this server block.
# The request and response objects are semi-mutable, see: webstack2.rb.
Webstack::Server.new do |stack, request, response|
Throttle::Middleware.new(request)
Protection::Middleware.new(request)
TempfileManager::Middleware.new(request)
Deserializer::Middleware.new(request)
Dispatcher.new(stack)
ContentLengthSetter::Middleware.new(response)
ContentTypeSetter::Middleware.new(response)
AcceptSetter::Middleware.new(response)
Serializer::Middleware.new(response)
end
# Each middleware piece is handed the appropriate part, allowed to mutate
# sub-sections, and then is garbage collected.
# If a middleware encounters a problem it can do one of two things:
# - Halt the stack with a status code (4XX, 5XX), see: throttle & protection
# - Add an error body instead of a mutated raw, see: deserializer & tempfile_manager
# This allowes the stack designer to handle errors in the desired
# way.
#
# Pros:
# - Each middleware is given a clear designation on the cycle
# - Raw data isn't mutated, ever, allowing access to known untainted information
# - The stack is clean and clear cut, defining boundries for middleware
# - The middleware is capable of being immutable
# - Error handling is no longer up to the middleware developer, no more
# json error responses in your XML endpoint
# - Middleware can now share behavior
# - It's efficient to debug the process, as things happen once and get
# memoized.
# - Middleware can't fuck with other middleware.
#
# Cons:
# - No more `#call` affinity, so no more Procs or Lambdas.
# - Might be bigger in memory with the multiple states, keys, etc.
# The content of response
{
# raw is immutable
"raw" => {
"request" => "GET /accounts?limit=10",
"header" => {
"Content-Type" => "application/json",
"Accept" => "application/json"
},
"body" => #<StringIO#f2edasd>
},
# modified is writable but no overwrites or deletes
"modified" => {
"webstack" => {
"verb" => :get,
"path" => "/accounts",
"query" => {
"limit" => 10
},
"header" => {
"Content-Type" => "application/json",
"Accept" => "application/json"
}
"body" => #<StringIO#f2edasd>
},
"throttle::middleware" => {
# ... throttles mutated version of raw ...
}
# ... Other middleware's versions of raw ...
}
}
# At the end all of modified's headers & query are merged and last body, verb, path, status are used.
# The content of request
{
"webstack" => {
"status" => 200,
"header" => {},
"body" => nil
},
"content_length_setter::middleware" => {
"header" => {
"Content-Length" => 300
},
"body" => nil
}
# ... Other middleware's structs ...
}
# At the end all headers are merged and last body & status are used.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment