$30 off During Our Annual Pro Sale. View Details »

Surrounded by Microservices

Surrounded by Microservices

The slides for the 'Surrounded by Microservices' talk , Euruko 2019, Rotterdam.

DamirSvrtan

June 21, 2019
Tweet

More Decks by DamirSvrtan

Other Decks in Programming

Transcript

  1. Surrounded by
    Microservices

    View Slide

  2. The DVD Rental Company

    View Slide

  3. Video on demand

    View Slide

  4. Original content

    View Slide

  5. Big Shift?

    View Slide

  6. Old industry
    !

    View Slide

  7. Remember these?

    View Slide

  8. Problem space
    !

    View Slide

  9. Studio apps

    View Slide

  10. Starting with a monolith

    View Slide

  11. Specialization
    !

    View Slide

  12. Starting fresh
    !

    View Slide

  13. Ruby On Rails
    !

    View Slide

  14. The Active Record Pattern
    !
    Domain Objects
    "
    Business Rules
    #
    Validations
    $
    Persistence

    View Slide

  15. Distributed data
    !

    View Slide

  16. Various data sources
    !
    REST API
    "
    JSON API
    #
    GRPC
    $
    GraphQL
    %
    Local Database

    View Slide

  17. "Data that lives in our database today
    might live in a service tomorrow"

    View Slide

  18. Architecture that clearly separates
    the business logic from any kind of
    implementation details and protocols

    View Slide

  19. Hexagonal
    Architecture

    View Slide

  20. View Slide

  21. Core concepts

    View Slide

  22. Entities

    View Slide

  23. The repositories

    View Slide

  24. The data sources

    View Slide

  25. Interactors

    View Slide

  26. Implementing
    business logic

    View Slide

  27. Entities
    module Workflows
    class ProductionEntity < BaseEntity
    attribute :id, AttrType::Strict::Integer
    attribute :title, AttrType::Strict::String
    attribute :logline, AttrType::Strict::String.optional
    end
    end

    View Slide

  28. dry-struct

    View Slide

  29. Entities
    class ProductionEntity < BaseEntity
    attribute :id, AttrType::Strict::Integer
    attribute :title, AttrType::Strict::String
    attribute :logline, AttrType::Strict::String.optional
    end

    View Slide

  30. Repositories (Custom DSL)
    class ProductionRepo < BaseRepo
    entity_class ProductionEntity
    def initialize(data_source: MovieProduction)
    super
    end
    def find_by_id(id)
    wrap(data_source.find_by_id(id))
    end
    def search_by_title(title)
    wrap(data_source.search_by_title(title))
    end
    end

    View Slide

  31. Data Sources
    class MovieProduction < ApplicationRecord
    def self.search_by_title(title)
    where('title LIKE ?', "#{sanitize_sql_like(title)}%") }
    end
    end

    View Slide

  32. Data Sources
    class MovieProductionAPI
    def self.search_by_title(title)
    SwaggerClient::MovieProductionsApi.advanced_search(
    search_param: title,
    headers: { ... },
    ...
    )
    end
    end

    View Slide

  33. Data Source Independent
    # using the default data source
    repo = ProductionRepo.new
    # swapping for a REST API data source
    repo = ProductionRepo.new(data_source: MovieProductionAPI)

    View Slide

  34. Interactor gem

    View Slide

  35. Interactors
    module Workflows
    class OnboardProduction
    include NetflixInteractor
    def self.call(production_id:, vertical_id:, repo: ProductionRepo.new)
    super
    end
    def call
    # validate inputs
    # is it okay to onboard a production?
    # cover edge cases
    # notify others about a production being onboarded
    end
    end
    end

    View Slide

  36. Hanami

    View Slide

  37. Implementing
    data sources

    View Slide

  38. API Clients

    View Slide

  39. Handwritten API Clients

    View Slide

  40. Autogenerated API Clients

    View Slide

  41. Autogenerated API Clients
    Swagger Code Generator
    GRPC
    JSON API Spec

    View Slide

  42. Dealing with
    errors

    View Slide

  43. The network is unreliable

    View Slide

  44. Graceful failure

    View Slide

  45. Logging downstream requests

    View Slide

  46. Metrics

    View Slide

  47. Error reporting

    View Slide

  48. Errors Must Be Actionable

    View Slide

  49. Avoid Alarm Fatigue

    View Slide

  50. Setting up thresholds

    View Slide

  51. Going straight
    to the data
    source

    View Slide

  52. Does it scale?

    View Slide

  53. Eventual consistency

    View Slide

  54. Consistency vs availability

    View Slide

  55. "Services should respond in a timely
    manner"

    View Slide

  56. What's in the future?

    View Slide

  57. Delaying
    decisions

    View Slide

  58. Project paradox

    View Slide

  59. The purpose of a good architecture is to delay decisions.
    Why? Because when we delay a decision, we have more
    information when it comes time to make it.
    - Uncle Bob

    View Slide

  60. Postgres? Cassandra? Redis?
    Elasticsearch?

    View Slide

  61. Testing
    Strategy

    View Slide

  62. The test suite must be reliable and fast

    View Slide

  63. Rails Testing

    View Slide

  64. Testing business logic

    View Slide

  65. Dependency Injection

    View Slide

  66. Testing with verified doubles
    describe Workflows::OnboardProduction do
    let(:production_id) { SecureRandom.uuid }
    let(:vertical_id) { SecureRandom.uuid }
    let(:response) do
    described_class.call(production_id: production_id, vertical_id: vertical_id, repo: repo)
    end
    describe 'when a production already exists' do
    let(:repo) { instance_double(Workflow::ProductionRepo, find_by_id: existing_production) }
    it 'the response is a failure' do
    expect(response).to be_a_failure
    end
    end
    ...
    end

    View Slide

  67. Integration specs
    data sources & end to end

    View Slide

  68. A fast and reliable spec
    suite
    Finished in 1 minute 2.35 seconds (files took 2.93 seconds to load)
    2015 examples, 0 failures

    View Slide

  69. Conclusion

    View Slide

  70. Separate business
    logic from
    implementation
    details

    View Slide

  71. Delay decisions

    View Slide

  72. Damir Svrtan
    Twitter: @DamirSvrtan

    View Slide