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

Purely Functional Web Apps

Purely Functional Web Apps

Are you familiar with the following recipe?
- First define an API and its documentation.
- Then take the API and create its server implementation.
- Then create a client for the same API, but in JavaScript land.
- Then imperatively modify the browser’s DOM in order to allow user to do and see stuff.

Sounds about right?

During this talk you will forget about all these things and become a functional web developer. I will show you how to write type-level web APIs, purely functional server and client implementations and how to render things without touching browser’s DOM.

The talk is divided into two parts: backend & frontend. The first part of the talk will introduce the concepts behind haskell-servant and we will implement a simple web app backend. Then we will code the app itself using Elm and reactive approach.

Michał Płachta

February 19, 2016
Tweet

More Decks by Michał Płachta

Other Decks in Programming

Transcript

  1. days / Kraków / 19.02.2016
    FUNCTIONAL
    WEB APPS
    Michał Płachta
    @miciek
    PURELY
    SUCH
    PURE

    View Slide

  2. days / Kraków / 19.02.2016
    @miciek
    Let’s create a full-blown
    web application

    View Slide

  3. days / Kraków / 19.02.2016
    @miciek
    MAIN DEV GOALS
    ■ explicit external dependencies
    ■ explicit side effects
    ■ explicit configuration
    ■ explicit error handling
    pure functions & strong types
    Solution:

    View Slide

  4. days / Kraków / 19.02.2016
    @miciek
    Gitlab

    View Slide

  5. days / Kraków / 19.02.2016
    @miciek
    Merge Request Stats
    Gitlab Our app

    View Slide

  6. days / Kraków / 19.02.2016
    @miciek
    Application Architecture
    Gitlab Server
    Merge Request
    Fetcher
    MR Stats
    Web Service
    In Memory
    Storage
    MR Stats
    Web Application
    data flow

    View Slide

  7. days / Kraków / 19.02.2016
    @miciek
    Haskell & Elm
    Gitlab Server
    Merge Request
    Fetcher
    MR Stats
    Web Service
    In Memory
    Storage
    MR Stats
    Web Application
    Elm
    data flow

    View Slide

  8. days / Kraków / 19.02.2016
    @miciek
    One slide Haskell tutorial

    View Slide

  9. days / Kraków / 19.02.2016
    @miciek
    Using Servant as
    HTTP Client

    View Slide

  10. days / Kraków / 19.02.2016
    @miciek
    Haskell Servant
    ■ set of libraries
    ■ for HTTP related stuff
    ■ DRY
    ■ type safe
    ■ type level DSL

    View Slide

  11. days / Kraków / 19.02.2016
    @miciek
    Let’s start with the Fetcher
    Gitlab Server
    Merge Request
    Fetcher
    MR Stats
    Web Service
    In Memory
    Storage
    MR Stats
    Web Application
    data flow

    View Slide

  12. days / Kraków / 19.02.2016
    @miciek
    Gitlab API

    View Slide

  13. days / Kraków / 19.02.2016
    @miciek
    Merge Request JSON

    View Slide

  14. days / Kraków / 19.02.2016
    @miciek
    Merge Request Data Type

    View Slide

  15. days / Kraków / 19.02.2016
    @miciek
    Evil smiley face emoticon
    :>

    View Slide

  16. days / Kraków / 19.02.2016
    @miciek
    API Type
    /api/v3/projects/{projectId}/merge_requests/?page={page}

    View Slide

  17. days / Kraków / 19.02.2016
    @miciek
    apiQuery Function Type
    URL to query

    View Slide

  18. days / Kraków / 19.02.2016
    @miciek
    queryApi Return Type
    EitherT
    ServantError
    IO
    Paged
    [MergeRequest]

    View Slide

  19. days / Kraków / 19.02.2016
    @miciek
    IO Type
    IO
    Paged
    [MergeRequest]
    ■ side effecting
    ■ an action
    ■ e.g. get something
    from the server
    ■ can’t get rid of it
    Nope

    View Slide

  20. days / Kraków / 19.02.2016
    @miciek
    Quick IO Side Note
    What’s the difference?
    Examples from Haskell

    View Slide

  21. days / Kraków / 19.02.2016
    @miciek
    EitherT
    EitherT
    ServantError IO
    ■ can be either Left or Right
    ■ Left contains ServantError
    ■ Right contains IO a

    View Slide

  22. days / Kraków / 19.02.2016
    @miciek
    apiQuery implementation
    client is a Servant
    function that looks at
    our type and provides
    the implementation

    View Slide

  23. days / Kraków / 19.02.2016
    @miciek
    Nicer API with AppConfig

    View Slide

  24. days / Kraków / 19.02.2016
    @miciek
    pagedMergeRequests function
    ■ Maybe a type can be
    ○ Just a
    ○ Nothing

    View Slide

  25. days / Kraków / 19.02.2016
    @miciek
    allMergeRequests function
    uses

    View Slide

  26. days / Kraków / 19.02.2016
    @miciek
    allMergeRequests implementation
    EitherT ServantError IO
    context
    pagedResponse has type Paged [MergeRequest]

    View Slide

  27. days / Kraków / 19.02.2016
    @miciek
    Side Effects without IO?

    View Slide

  28. days / Kraków / 19.02.2016
    @miciek
    Merge Request Fetcher module

    View Slide

  29. days / Kraków / 19.02.2016
    @miciek
    Same story: Comments

    View Slide

  30. days / Kraków / 19.02.2016
    @miciek
    Business Logic: Stats Calculations
    ■ title
    ■ create date
    ■ last update date
    ■ upvotes
    ■ downvotes
    ■ list of comments
    ■ Merge Request object
    ■ time to merge (calculated)
    ■ comments quantity (calculated)
    ■ url to the MR
    Merge Request (from Gitlab) Merge Request Stats (ours)

    View Slide

  31. days / Kraków / 19.02.2016
    @miciek
    calculateStats function
    NOOO
    IOooo!!!
    It’s good,
    right?

    View Slide

  32. days / Kraków / 19.02.2016
    @miciek
    fetchMRsAndSaveStats function

    View Slide

  33. days / Kraków / 19.02.2016
    @miciek
    Serving the stats

    View Slide

  34. days / Kraków / 19.02.2016
    @miciek
    main function

    View Slide

  35. days / Kraków / 19.02.2016
    @miciek
    We did it!
    Merge Request
    Fetcher
    MR Stats
    Web Service
    In Memory
    Storage

    View Slide

  36. days / Kraków / 19.02.2016
    @miciek
    Automatic JS client and Markdown!

    View Slide

  37. days / Kraków / 19.02.2016
    @miciek
    Let’s do the frontend
    Gitlab Server
    Merge Request
    Fetcher
    MR Stats
    Web Service
    In Memory
    Storage
    MR Stats
    Web Application
    ■ using Elm
    ■ merge request stats in a table
    ■ dynamically updated each 5 seconds

    View Slide

  38. days / Kraków / 19.02.2016
    @miciek
    Elm architecture
    Elm Runtime
    Model
    update
    Action
    New
    Model
    view
    Effect
    Html
    Object
    Elm Rendering

    View Slide

  39. days / Kraków / 19.02.2016
    @miciek
    Elm architecture in types

    View Slide

  40. days / Kraków / 19.02.2016
    @miciek
    Our Model

    View Slide

  41. days / Kraków / 19.02.2016
    @miciek
    Our Actions

    View Slide

  42. days / Kraków / 19.02.2016
    @miciek
    update Function

    View Slide

  43. days / Kraków / 19.02.2016
    @miciek
    mergeRequestsFetchEffect

    View Slide

  44. days / Kraków / 19.02.2016
    @miciek
    view = virtual DOM objects

    View Slide

  45. days / Kraków / 19.02.2016
    @miciek
    Effects are Data
    Elm Runtime
    MRs &
    refresh
    time
    update
    Tick or
    Update
    List
    Action
    MRs &
    refresh
    time
    view
    Tick or
    Fetch
    Effect
    MRs
    Table
    Object
    Elm Rendering

    View Slide

  46. days / Kraków / 19.02.2016
    @miciek
    Fame & Glory

    View Slide

  47. days / Kraków / 19.02.2016
    @miciek
    Time Travel Debugger
    See for yourself: http://debug.elm-lang.org/edit/Mario.elm

    View Slide

  48. days / Kraków / 19.02.2016
    @miciek
    Links
    ■ Backend project: https://github.com/miciek/mr-stats-haskell-
    servant
    ■ Frontend project: https://github.com/miciek/mr-stats-frontend-
    elm
    ■ Elm architecture tutorial: https://github.com/evancz/elm-
    architecture-tutorial
    ■ Haskell Servant: https://github.com/haskell-servant/servant
    ■ Let’s be mainstream - user-focused design in Elm: https://www.
    youtube.com/watch?v=oYk8CKH7OhE
    ■ Monad Transformers: https://www.youtube.com/watch?
    v=pzouxmWiemg
    ■ Make the backend team jealous - Elm in Production: https://www.
    youtube.com/watch?v=FV0DXNB94NE
    ■ Children do projects using Elm: http://outreach.mcmaster.
    ca/tutorials/shapes/shapes.html

    View Slide

  49. days / Kraków / 19.02.2016
    PURELY FUNCTIONAL
    WEB APPS
    Michał Płachta
    www.michalplachta.com
    @miciek
    THANK YOU!

    View Slide