Skip to content

Instantly share code, notes, and snippets.

@blaix
Created June 3, 2015 19:56
Show Gist options
  • Save blaix/583e995554ff45af966b to your computer and use it in GitHub Desktop.
Save blaix/583e995554ff45af966b to your computer and use it in GitHub Desktop.
# single-purpose objects for handling requests:
class CreateArticle
attr_reader :repo, :validations
def initialize(repo:, validator:)
@repo = repo
@validator = validator
end
def call(params)
# do the work...
end
end
# single-purpose objects for handling responses:
class RenderArticle
# you get the idea...
end
# explicitly create your objects, don't expect certain classes
# to live in certain places with certain names.
# inject dependencies as needed (because initializers aren't hijacked via inheritence)
create_article = CreateArticle.new(repo: ArticleRepo.new, validator: ArticleValidations.new)
render_article = RenderArticle.new(view: ArticleView.new)
router = DreamFramework::Router.new do
# a "resource" is defined by URL, not by entity (REST-friendly)
resource "articles", at: "/articles" do
# forget controllers, map request attributes directly to single-purpose objects:
on POST, call: create_article, with: -> (req) { req.params[:article] }, then: render_article
end
end
# with other libraries for supporting view stuff, persistence stuff, etc...
# It should all work together as a framework, but it should feel like interacting with a cohesive set of libraries
# more than plugging things into certain slots to make a framework happy.
# You should be calling the 3rd party code, the 3rd party code shouldn't be finding and calling your code.
@blaix
Copy link
Author

blaix commented Jun 3, 2015

Even better, have factory objects with methods for returning your request/response handlers that you pass to the router, and the routes could accept strings for the handler names (matching factory method names) instead of the actual objects. Then you could test your router without needing to declare actual handlers.

@blaix
Copy link
Author

blaix commented Jun 3, 2015

Note that we aren't passing a request object to a request handler, we're mapping request attributes into call attribute. The request handler doesn't care about HTTP requests, it only cares about the business logic it's implementing.

@blaix
Copy link
Author

blaix commented Jun 3, 2015

on ValidationError, call: ...

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment