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 Slide

  2. GRZEGORZ

    View Slide

  3. GRZEGORZ

    View Slide

  4. View Slide

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

    View Slide

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

    View Slide

  7. 7
    Exploration Familiarity
    WHY WE CHOSE HANAMI?

    View Slide

  8. 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 Slide

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

    View Slide

  10. PART 1:
    THE WEB

    View Slide

  11. 11
    HANAMI WEB GEMS
    router
    controller
    view
    helpers

    View Slide

  12. 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 Slide

  13. 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 Slide

  14. 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 Slide

  15. 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 Slide

  16. 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 Slide

  17. 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 Slide

  18. 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 Slide

  19. 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 Slide

  20. 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 Slide

  21. 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 Slide

  22. PART 2:
    THE DATA

    View Slide

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

    View Slide

  24. 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 Slide

  25. 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 Slide

  26. 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 Slide

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

    View Slide

  28. 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 Slide

  29. PART 3:
    APPLICATION

    View Slide

  30. 30
    HANAMI APPLICATION GEMS
    hanami
    cli

    View Slide

  31. 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 Slide

  32. 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 Slide

  33. 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 Slide

  34. 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 Slide

  35. PART 4:
    SUPPORT

    View Slide

  36. 36
    HANAMI SUPPORT GEMS
    mailer
    utils

    View Slide

  37. 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 Slide

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

    View Slide

  39. 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 Slide

  40. 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 Slide

  41. 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 Slide

  42. PART 5:
    SUMMARY

    View Slide

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

    View Slide

  44. 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 Slide

  45. WE’RE HIRING

    View Slide

  46. GRZEGORZ

    View Slide

  47. GRZEGORZ

    View Slide

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

    View Slide