Mining gems in your existing codebase

  • View
    132

  • Download
    0

Embed Size (px)

Text of Mining gems in your existing codebase

  1. 1. Mining gems in your existing codebase @sanderhahn amsterdam ruby meetup 17th Dec 2014
  2. 2. Agenda Why extract gems? Prevent Rails apps to grow into monoliths How to design more modular apps? Railties, plugins, engines and mountables Ready for microservices? Just a perspective, open for discussion and your milage may vary
  3. 3. How Rails evolves Rails is a collection of separate gems living inside a single git repository (synchronised release planning and versions) Deprecation is done by including and extracting functionality into separate gems to allow managing technical debt (optional use of new and legacy gems)
  4. 4. Evolution by inclusion and extraction attr_accessible moved into protected_attributes gem, replaced by strong_parameters gem responds_with into responders gem cache_digests gem asset pipeline into sprockets-rails gem active_resource gem
  5. 5. Rails apps are structured by type app/assets app/controllers app/models app/views cong/routes.rb db/migrate
  6. 6. Monolithic apps Rails development is very fast in greeneld projects but can become slower as your application and team grows Tests might require large xtures of unrelated data and can take a long time to run
  7. 7. Engines enable apps to be structured by function Website Content Newsletter Subscription Lead Generation Webshop Public API
  8. 8. Advantages Apps are build from logical separate modules with explicit boundaries Distribute responsibility of code and work in a team Code reuse in client projects is possible Tests are more isolated and run faster Technical dept is easier to manage
  9. 9. Guiding principles Loosely coupled system is one in which each of its components has little or no knowledge of the denitions of other separate components High cohesion means to keep similar and related things together which share the same responsibility or goal
  10. 10. How to dissect apps into modular gems Railties (initialization) Plugins (extend Rails functionality) Engines (app composition) Mountable's (isolated namespace and route)
  11. 11. Foundation of Rails # rails/railtie.rb class Railtie # rails/engine.rb class Engine < Railtie # rails/application.rb class Application < Engine # cong/application.rb class Application < Rails::Application
  12. 12. Railtie provides several hooks to extend Rails and/or modify the initialization process
  13. 13. Rails components are Railties
  14. 14. ActionMailer example
  15. 15. Plugin is an extension or a modication of the core framework
  16. 16. Plugin structure $ rails plugin new gems/myplugin
  17. 17. Gem dependencies
  18. 18. Plugin cong with Railtie
  19. 19. Engine is a miniature application that provides functionality to its host application
  20. 20. Engine structure $ rails plugin new gems/myengine --full
  21. 21. Rails generate/destroy are available inside an engine $ cd gems/myengine $ rails generate scaffold user name:string $ cd ../.. # add dependency in Gemle $ rake myengine:install:migrations
  22. 22. Mountable is a namespace- isolated engine
  23. 23. Mountable structure $ rails plugin new gems/mymountable --mountable
  24. 24. Rails inside a mountable $ cd gems/mymountable $ rails generate scaffold post user:references title:string $ cd ../.. # add dependency in Gemle $ rake mymountable:install:migrations
  25. 25. Engine vs mountables
  26. 26. Cross engine url_helpers
  27. 27. Testing an engine At application runtime all engines are available Integration testing is done by creating a dummy app inside the test dir Other engines are only available if specied as a dependency Fake models and migrations can be created in the dummy app on engine boundaries
  28. 28. Dummy app for integration test in the devise gem
  29. 29. Example: Tolk gem is a Rails engine for translating your app to other languages
  30. 30. Tolk structure
  31. 31. Tolk generator
  32. 32. Thor and Generator actions
  33. 33. Breaking the Monolith @ Soundcloud We decided to move towards what is now known as a microservices architecture. In this style, engineers separate domain logic into very small components. These components expose a well-dened API, and implement a Bounded Context including its persistence layer and any other infrastructure needs. In the end, the team decided to use Rails' features of engines to create an Internal API that is available only within our private network. http://www.slideshare.net/pcalcado/from-a-monolithic-ruby-on-rails-app-to-the-jvm https://developers.soundcloud.com/blog/building-products-at-soundcloud-part-1-dealing-with-the-monolith https://developers.soundcloud.com/blog/building-products-at-soundcloud-part-2-breaking-the-monolith https://developers.soundcloud.com/blog/building-products-at-soundcloud-part-3-microservices-in-scala-and-nagle
  34. 34. Engines vs microservices Microservice architectural style: designing software applications as suites of independently deployable services http://martinfowler.com/articles/microservices.html
  35. 35. Bounded Context helps guiding engine design Domain-driven design (DDD) deals with large models by dividing them into different Bounded Contexts and being explicit about their interrelationships http://martinfowler.com/bliki/BoundedContext.html
  36. 36. Thank you!