Upgrade to Pro — share decks privately, control downloads, hide ads and more …

One Year with Hanami

One Year with Hanami

Have you ever heard of Hanami? Have you considered using it for your new project, but you don’t know what to expect? This talk will clear your doubts - my team has been using Hanami for more than a year and I’m going to share our experience with the framework.

Grzegorz Witek

August 04, 2018
Tweet

More Decks by Grzegorz Witek

Other Decks in Technology

Transcript

  1. ONE YEAR WITH
    HANAMI
    @ A R N V A L D , P U N E , 2 0 1 8

    View full-size slide

  2. 5
    WHAT IS HANAMI
    • long-standing Japanese tradition
    of welcoming spring
    • web framework written in Ruby
    image source: https://hanamirb.org

    View full-size slide

  3. 6
    BRIEF INTRODUCTION
    Hanami is a full-featured web framework
    Hanami is modular
    Hanami is lightweight
    Hanami promotes good practices

    View full-size slide

  4. 7
    Exploration Familiarity
    WHY WE CHOSE HANAMI?

    View full-size slide

  5. 8
    OUR TIMELINE
    June 2017
    R U N N I N G
    P R O D U C T I O N
    January 2017
    F I R S T
    C O M M I T
    July 2017
    2 N D
    A P P L I C A T I O N
    March 2018
    H A N A M I 1 . 1

    View full-size slide

  6. 9
    OUTLINE
    The web part
    The data part
    The application part
    The support part

    View full-size slide

  7. PART 1:
    THE WEB

    View full-size slide

  8. 11
    HANAMI WEB GEMS
    router
    controller
    view
    helpers

    View full-size slide

  9. 12
    Each action is a separate class
    with call method.
    Testing controller is as simple
    as calling
    Action.new.call(params)
    one controller
    action =
    one class

    View full-size slide

  10. 13
    Each action is a separate class
    with call method.
    Testing controller is as simple
    as calling
    Action.new.call(params)
    one controller
    action =
    one class
    /apps

    /admin

    /config

    /controllers

    /orders

    /index.rb

    /create.rb

    /customers

    /index.rb

    /create.rb

    View full-size slide

  11. 14
    controller
    actions are
    magical
    Hanami Action module wraps
    around your class’ call method.
    The value you return from call is
    ignored, instead you must
    modify class’ attributes

    View full-size slide

  12. 15
    controller
    actions are
    magical
    Hanami Action module wraps
    around your class’ call method.
    The value you return from call is
    ignored, instead you must
    modify class’ attributes
    class Index

    include MyApp::Action


    def call(params)

    “this is action”

    end

    end
    Index.new.call({})
    [200,

    … a lot of headers,

    []]

    View full-size slide

  13. 16
    controller
    actions are
    magical
    Hanami Action module wraps
    around your class’ call method.
    The value you return from call is
    ignored, instead you must
    modify class’ attributes
    class Index

    include MyApp::Action


    def call(params)

    status 200, “this is action”

    end

    end
    Index.new.call({})
    [200,

    … a lot of headers,

    [“this is action”]]

    View full-size slide

  14. 17
    controller
    actions are
    magical
    Hanami Action module wraps
    around your class’ call method.
    The value you return from call is
    ignored, instead you must
    modify class’ attributes
    class Index

    include MyApp::Action


    def call(params)

    self.body = “this is action”

    self.status = 403

    end

    end
    Index.new.call({})
    [403,

    … a lot of headers,

    [“this is action”]]

    View full-size slide

  15. 18
    Views in Hanami are objects
    that encapsulate logic that is
    used in the template
    Templates are representation of
    the data returned to the user
    views !=
    templates

    View full-size slide

  16. 19
    Views in Hanami are objects
    that encapsulate logic that is
    used in the template
    Templates are representation of
    the data returned to the user
    views !=
    templates
    # view

    class Index

    include MyApp::View


    def users_age

    Time.now.year - user.year_of_birth

    end

    end
    # template



    <%= users_age %>



    View full-size slide

  17. 20
    Views in Hanami are objects
    that encapsulate logic that is
    used in the template
    Templates are representation of
    the data returned to the user
    built-in
    helpers are
    private

    View full-size slide

  18. 21
    Views in Hanami are objects
    that encapsulate logic that is
    used in the template
    Templates are representation of
    the data returned to the user
    built-in
    helpers are
    private
    # view

    class Index

    include MyApp::View


    def total_cost

    format_number(cost)

    end

    end
    # template



    <%= total_cost %>



    View full-size slide

  19. PART 2:
    THE DATA

    View full-size slide

  20. 23
    HANAMI DATA GEMS
    model
    validations
    events (experimental)

    View full-size slide

  21. 24
    Repository pattern separates
    the entities (individual objects)
    from the repository (a collection
    of objects)
    It means that queries will be in
    different class than individual
    object methods
    repository
    pattern

    View full-size slide

  22. 25
    Repository pattern separates
    the entities (individual objects)
    from the repository (a collection
    of objects)
    It means that queries will be in
    different class than individual
    object methods
    repository
    pattern
    class OrderRepository < Hanami::Repository

    associations do

    belongs_to :customer

    end 


    def future

    orders.where { delivered_at.is(nil() }

    end

    end
    class Order < Hanami::Entity

    def description

    “#{product.name} #{total_cost}”

    end

    end

    View full-size slide

  23. 26
    3 layers
    around the
    database
    Hanami model library relies on
    Rom-rb which relies on Sequel
    Sometimes we can’t achieve
    what we want in Hanami model
    and we need to go down to
    another layer of abstraction

    View full-size slide

  24. 27
    Validations are a mixin that can
    be included anywhere - they
    perfectly fit controllers or
    service objects
    validations
    separated
    from entities

    View full-size slide

  25. 28
    Validations are a mixin that can
    be included anywhere - they
    perfectly fit controllers or
    service objects
    validations
    separated
    from entities
    class Create

    include MyApp::Action


    params do

    required(:title).filled(:str?)

    required(:amount).filled(:int?)

    end

    end


    class CreateOrder

    include Hanami::Validations


    validations do

    required(:title).filled(:str?)

    end

    end

    View full-size slide

  26. PART 3:
    APPLICATION

    View full-size slide

  27. 30
    HANAMI APPLICATION GEMS
    hanami
    cli

    View full-size slide

  28. 31
    Starting a new Hanami project
    creates /apps directory with one
    application there
    Having multiple applications in
    one project is not a special
    case, but a standard
    mountable
    apps are first
    class citizens

    View full-size slide

  29. 32
    Starting a new Hanami project
    creates /apps directory with one
    application there
    Having multiple applications in
    one project is not a special
    case, but a standard
    mountable
    apps are first
    class citizens
    /apps

    /admin

    /config

    /controllers

    /orders

    /customers

    /web

    /config

    /controllers

    /api

    /config

    /controllers

    View full-size slide

  30. 33
    not that
    modular
    Hanami libraries are
    independent of each other.
    However, Hanami application
    gem relies on most of the gems.
    Even if you don’t need mailers -
    you’ll have them in Gemfile.lock

    View full-size slide

  31. 34
    Hanami promotes good
    engineering practices:
    separating layers of the
    application, writing code that’s
    easy to test, making most of the
    code private
    emphasis on
    architecture

    View full-size slide

  32. PART 4:
    SUPPORT

    View full-size slide

  33. 36
    HANAMI SUPPORT GEMS
    mailer
    utils

    View full-size slide

  34. 37
    Hanami utils do not monkey
    patch standard Ruby classes.
    Instead they add their own
    classes on top of the standard
    ones
    no monkey
    patching

    View full-size slide

  35. 38
    Hanami utils gem provides a
    simple class that helps
    implementing service objects in
    a consistent manner
    interactors

    View full-size slide

  36. 39
    magic in
    interactors
    Similarly to controller actions,
    the result is based on instance
    variables, not on the value you
    return from your call function

    View full-size slide

  37. 40
    magic in
    interactors
    class CreateUser

    include Hanami::Interactor


    expose :user


    def call(params)

    @user = User.new(params)

    end

    end


    creator = CreateUser.new

    result = creator.call(params)

    result.user
    Similarly to controller actions,
    the result is based on instance
    variables, not on the value you
    return from your call function

    View full-size slide

  38. 41
    small
    ecosystem
    Hanami is still considered a new
    framework, despite being more
    than 3 years old.
    There’s still few resources and
    libraries that help develop
    Hanami applications

    View full-size slide

  39. PART 5:
    SUMMARY

    View full-size slide

  40. 43
    YOU CAN USE HANAMI FOR
    most web applications
    even non-web applications (model, validations, mailers)

    View full-size slide

  41. 44
    YOU MIGHT RECONSIDER IF YOU BUILD
    application that needs a lot of external libraries
    project with a lot of complex queries
    simple CRUD applications

    View full-size slide

  42. WE’RE HIRING

    View full-size slide

  43. ONE YEAR WITH
    HANAMI
    @ A R N V A L D , P U N E , 2 0 1 8
    wonderful

    View full-size slide