Top Banner
lounge / Kraków / 16.02.2016 FUNCTIONAL WEB APPS Michał Płachta @miciek PURELY SUCH PURE
51

Purely Functional Web Apps (Extended Version, 16.02.2016)

Apr 12, 2017

Download

Software

miciek
Welcome message from author
This document is posted to help you gain knowledge. Please leave a comment to let me know what you think about it! Share it to your friends and learn new things together.
Transcript
Page 1: Purely Functional Web Apps (Extended Version, 16.02.2016)

lounge / Kraków / 16.02.2016

FUNCTIONALWEB APPS

Michał Płachta@miciek

PURELY

SUCHPURE

Page 2: Purely Functional Web Apps (Extended Version, 16.02.2016)

lounge / Kraków / 16.02.2016@miciek

Let’s create a full-blown web application

Page 3: Purely Functional Web Apps (Extended Version, 16.02.2016)

lounge / Kraków / 16.02.2016@miciek

MAIN DEV GOALS■ explicit external dependencies■ explicit side effects■ explicit configuration■ explicit error handling

pure functions & strong typesSolution:

Page 4: Purely Functional Web Apps (Extended Version, 16.02.2016)

lounge / Kraków / 16.02.2016@miciek

Gitlab

Page 5: Purely Functional Web Apps (Extended Version, 16.02.2016)

lounge / Kraków / 16.02.2016@miciek

Merge Request StatsGitlab Our app

Page 6: Purely Functional Web Apps (Extended Version, 16.02.2016)

lounge / Kraków / 16.02.2016@miciek

Application Architecture

Gitlab Server

Merge RequestFetcher

MR StatsWeb Service

In MemoryStorage

MR StatsWeb Application

data flow

Page 7: Purely Functional Web Apps (Extended Version, 16.02.2016)

lounge / Kraków / 16.02.2016@miciek

Haskell & Elm

Gitlab Server

Merge RequestFetcher

MR StatsWeb Service

In MemoryStorage

MR StatsWeb Application

data flow

Elm

Page 8: Purely Functional Web Apps (Extended Version, 16.02.2016)

lounge / Kraków / 16.02.2016@miciek

One slide Haskell tutorial

Page 9: Purely Functional Web Apps (Extended Version, 16.02.2016)

lounge / Kraków / 16.02.2016@miciek

Using Servant asHTTP Client

Page 10: Purely Functional Web Apps (Extended Version, 16.02.2016)

lounge / Kraków / 16.02.2016@miciek

Haskell Servant■ set of libraries■ for HTTP related stuff■ DRY■ type safe■ type level DSL

Page 11: Purely Functional Web Apps (Extended Version, 16.02.2016)

lounge / Kraków / 16.02.2016@miciek

Let’s start with the Fetcher

Gitlab Server

Merge RequestFetcher

MR StatsWeb Service

In MemoryStorage

MR StatsWeb Application

data flow

Page 12: Purely Functional Web Apps (Extended Version, 16.02.2016)

lounge / Kraków / 16.02.2016@miciek

Gitlab API

Page 13: Purely Functional Web Apps (Extended Version, 16.02.2016)

lounge / Kraków / 16.02.2016@miciek

Merge Request JSON

Page 14: Purely Functional Web Apps (Extended Version, 16.02.2016)

lounge / Kraków / 16.02.2016@miciek

Merge Request Data Type

Page 15: Purely Functional Web Apps (Extended Version, 16.02.2016)

lounge / Kraków / 16.02.2016@miciek

API Type

/api/v3/projects/{projectId}/merge_requests/?page={page}

Page 16: Purely Functional Web Apps (Extended Version, 16.02.2016)

lounge / Kraków / 16.02.2016@miciek

apiQuery Function Type

URL to query

Page 17: Purely Functional Web Apps (Extended Version, 16.02.2016)

lounge / Kraków / 16.02.2016@miciek

queryApi Return Type

EitherT

ServantError

IO

Paged

[MergeRequest]

Page 18: Purely Functional Web Apps (Extended Version, 16.02.2016)

lounge / Kraków / 16.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

Page 19: Purely Functional Web Apps (Extended Version, 16.02.2016)

lounge / Kraków / 16.02.2016@miciek

Quick IO Side NoteWhat’s the difference?

Examples from Haskell

Page 20: Purely Functional Web Apps (Extended Version, 16.02.2016)

lounge / Kraków / 16.02.2016@miciek

EitherT

EitherT

ServantError IO

■ can be either Left or Right■ Left contains ServantError■ Right contains IO a

Page 21: Purely Functional Web Apps (Extended Version, 16.02.2016)

lounge / Kraków / 16.02.2016@miciek

ServantError

■ FailureResponse

■ DecodeFailure

■ UnsupportedContentType

■ ConnectionError

■ InvalidContentTypeHeader

Page 22: Purely Functional Web Apps (Extended Version, 16.02.2016)

lounge / Kraków / 16.02.2016@miciek

apiQuery implementation

client is a Servant function that looks at our type and provides the implementation

Page 23: Purely Functional Web Apps (Extended Version, 16.02.2016)

lounge / Kraków / 16.02.2016@miciek

Nicer API with AppConfig

Page 24: Purely Functional Web Apps (Extended Version, 16.02.2016)

lounge / Kraków / 16.02.2016@miciek

pagedMergeRequests function

■ Maybe a type can be○ Just a

○ Nothing

Page 25: Purely Functional Web Apps (Extended Version, 16.02.2016)

lounge / Kraków / 16.02.2016@miciek

allMergeRequests function

uses

Page 26: Purely Functional Web Apps (Extended Version, 16.02.2016)

lounge / Kraków / 16.02.2016@miciek

allMergeRequests implementation

Page 27: Purely Functional Web Apps (Extended Version, 16.02.2016)

lounge / Kraków / 16.02.2016@miciek

Side Note: Side Effects without IO?

Page 28: Purely Functional Web Apps (Extended Version, 16.02.2016)

lounge / Kraków / 16.02.2016@miciek

Merge Request Fetcher module

Page 29: Purely Functional Web Apps (Extended Version, 16.02.2016)

lounge / Kraków / 16.02.2016@miciek

Same story: Comments

Page 30: Purely Functional Web Apps (Extended Version, 16.02.2016)

lounge / Kraków / 16.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)

Page 31: Purely Functional Web Apps (Extended Version, 16.02.2016)

lounge / Kraków / 16.02.2016@miciek

calculateStats function

no IO!

Page 32: Purely Functional Web Apps (Extended Version, 16.02.2016)

lounge / Kraków / 16.02.2016@miciek

Now onto: In Memory Storage

Gitlab Server

Merge RequestFetcher

MR StatsWeb Service

In MemoryStorage

MR StatsWeb Application

data flow

Page 33: Purely Functional Web Apps (Extended Version, 16.02.2016)

lounge / Kraków / 16.02.2016@miciek

StatsStorage

Page 34: Purely Functional Web Apps (Extended Version, 16.02.2016)

lounge / Kraków / 16.02.2016@miciek

main function

Page 35: Purely Functional Web Apps (Extended Version, 16.02.2016)

lounge / Kraków / 16.02.2016@miciek

fetchMRsAndSaveStats function

Page 36: Purely Functional Web Apps (Extended Version, 16.02.2016)

lounge / Kraków / 16.02.2016@miciek

Serving the stats

Page 37: Purely Functional Web Apps (Extended Version, 16.02.2016)

lounge / Kraków / 16.02.2016@miciek

We did it!Merge Request

FetcherMR Stats

Web ServiceIn Memory

Storage

Page 38: Purely Functional Web Apps (Extended Version, 16.02.2016)

lounge / Kraków / 16.02.2016@miciek

Automatic JS client and Markdown!

Page 39: Purely Functional Web Apps (Extended Version, 16.02.2016)

lounge / Kraków / 16.02.2016@miciek

Let’s do the frontenddata flow

Gitlab Server

Merge RequestFetcher

MR StatsWeb Service

In MemoryStorage

MR StatsWeb Application

■ using Elm■ merge request stats in a table■ dynamically updated each 5 seconds

Page 40: Purely Functional Web Apps (Extended Version, 16.02.2016)

lounge / Kraków / 16.02.2016@miciek

Elm architecture

Elm Runtime

Model

update

Action

NewModel

view

Effect

HtmlObject

Elm Rendering

Page 41: Purely Functional Web Apps (Extended Version, 16.02.2016)

lounge / Kraków / 16.02.2016@miciek

Elm architecture in types

Page 42: Purely Functional Web Apps (Extended Version, 16.02.2016)

lounge / Kraków / 16.02.2016@miciek

Our Model

Page 43: Purely Functional Web Apps (Extended Version, 16.02.2016)

lounge / Kraków / 16.02.2016@miciek

Our Actions

■ UpdateList is generated inside the app■ Tick is generated outside of the app

Page 44: Purely Functional Web Apps (Extended Version, 16.02.2016)

lounge / Kraków / 16.02.2016@miciek

update Function

Page 45: Purely Functional Web Apps (Extended Version, 16.02.2016)

lounge / Kraków / 16.02.2016@miciek

mergeRequestsFetchEffect

Page 46: Purely Functional Web Apps (Extended Version, 16.02.2016)

lounge / Kraków / 16.02.2016@miciek

view = virtual DOM objects

Page 47: Purely Functional Web Apps (Extended Version, 16.02.2016)

lounge / Kraków / 16.02.2016@miciek

Effects are Data

Elm Runtime

MRs &refresh

time

update

Tick orUpdate

ListAction

MRs &refresh

time

view

Tick or FetchEffect

MRs TableObject

Elm Rendering

Page 48: Purely Functional Web Apps (Extended Version, 16.02.2016)

lounge / Kraków / 16.02.2016@miciek

DEMO TIME!

Fame & Glory

Page 49: Purely Functional Web Apps (Extended Version, 16.02.2016)

lounge / Kraków / 16.02.2016@miciek

Time Travel Debugger

See for yourself: http://debug.elm-lang.org/edit/Mario.elm

Page 50: Purely Functional Web Apps (Extended Version, 16.02.2016)

lounge / Kraków / 16.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

Page 51: Purely Functional Web Apps (Extended Version, 16.02.2016)

lounge / Kraków / 16.02.2016

PURELY FUNCTIONAL WEB APPS

Michał Płachtawww.michalplachta.com

@miciek

THANK YOU!