full stack scala

89
Full Stack Scala Scala in the backend and frontend! Ramnivas Laddad Founder, Paya Labs @ramnivas

Upload: ramnivas-laddad

Post on 21-Jan-2017

6.560 views

Category:

Internet


0 download

TRANSCRIPT

Page 1: Full Stack Scala

Full Stack ScalaScala in the backend and frontend!

Ramnivas LaddadFounder, Paya Labs

@ramnivas

Page 2: Full Stack Scala

@ramnivas

• Spring framework and Cloud Foundry contributor

• Main interests • Scala and functional programming • Cloud computing

• Author of books and articles • AspectJ in Action (1st and 2nd edition)

• Speaker at many professional conferences • JavaOne, ScalaDays, JavaPolis, SpringOne, Software

Development, No Fluff Just Stuff, OSCON etc.

Page 3: Full Stack Scala

A Quick Demo

Page 4: Full Stack Scala

High-level Architecture

API Server Static Page Server

html, js, css, …

GET, PUT, POST, DELETE

{ "name" : ...}

Page 5: Full Stack Scala

Backend Stack

Page 6: Full Stack Scala

API Server

API Server Static Page Server

html, js, css, …

GET, PUT, POST, DELETE

{ "name" : ...}

Page 7: Full Stack Scala

API Server

API Server Static Page Server

html, js, css, …

GET, PUT, POST, DELETE

{ "name" : ...}

Page 8: Full Stack Scala

Backend Structure

Page 9: Full Stack Scala

Backend Structure

Database

Page 10: Full Stack Scala

Backend Structure

DatabaseSendgrid

Page 11: Full Stack Scala

Backend Structure

DatabaseSendgridS3

Page 12: Full Stack Scala

Backend Structure

DatabaseSendgridS3

Page 13: Full Stack Scala

Backend Structure

DatabaseSendgridS3

Page 14: Full Stack Scala

Backend Structure

DatabaseSendgridS3

Page 15: Full Stack Scala

Backend Structure

Database

Data Access Layer

SendgridS3

Page 16: Full Stack Scala

Backend Structure

Database

Data Access Layer

SendgridS3

Talk by Rob NorrisPrograms as Values: JDBC Programming with Doobie

Page 17: Full Stack Scala

Backend Structure

Database

Data Access Layer

SendgridS3

Page 18: Full Stack Scala

Backend Structure

Database

Data Access Layer

SendgridS3

ApacheCommons

Page 19: Full Stack Scala

Backend Structure

Database

Data Access Layer

SendgridS3

ApacheCommons

AWSSDK

Page 20: Full Stack Scala

Backend Structure

Database

Data Access Layer

Service Layer

SendgridS3

ApacheCommons

AWSSDK

Page 21: Full Stack Scala

Backend Structure

Database

Data Access Layer

Service Layer

HTTP Layer

SendgridS3

ApacheCommons

AWSSDK

Page 22: Full Stack Scala

Frontend Stack

Page 23: Full Stack Scala

High-level Architecture

Static Page Server

html, js, css, …

API Server

GET, PUT, POST, DELETE

{ "name" : ...}

Page 24: Full Stack Scala

High-level Architecture

Static Page Server

html, js, css, …

API Server

GET, PUT, POST, DELETE

{ "name" : ...}

Page 25: Full Stack Scala

Serving static contentsvar express = require('express');var fs = require('fs');

var app = express();var port = process.env.PORT || 4000;

var devMode = process.env.SERVE_MODE != "SERVE_PROD";

var serveInfo = { dir: __dirname + ‘/dev-bin', maxAge: 0}if (!devMode) {

var oneHour = 60*60*1000;serveInfo = { dir: __dirname + ‘/prod-bin', maxAge: oneHour}

}

app.use(express.static(serveInfo.dir, { maxAge: serveInfo.maxAge }));

app.get('*', function(request, response, next) { response.sendFile(serveInfo.dir + '/index.html');});

app.listen(port, function() {console.log("Started on " + port + " (dev mode = " + devMode + ")\n");

});

Page 26: Full Stack Scala

High-level Architecture

API Server Static Page Server

html, js, css, …

GET, PUT, POST, DELETE

{ "name" : ...}

Page 27: Full Stack Scala

High-level Architecture

API Server Static Page Server

html, js, css, …

GET, PUT, POST, DELETE

{ "name" : ...}

Page 28: Full Stack Scala

Why Scala.js?

Page 29: Full Stack Scala

Why Scala.js?

Page 30: Full Stack Scala

Why Scala.js

Scala!

Page 31: Full Stack Scala

Why Scala.js

Static Types

Page 32: Full Stack Scala

Why Scala.js

Functional Programming

Page 33: Full Stack Scala

Why Scala.js

Isomorphism

Page 34: Full Stack Scala

Why Scala.js

Maturity!

Page 35: Full Stack Scala

Why Scala.js

Eco-system

Page 36: Full Stack Scala

UI Framework

Page 37: Full Stack Scala

Choosing a UI Framework

Page 38: Full Stack Scala

Choosing a UI FrameworkSimple

Mental Model

Page 39: Full Stack Scala

Choosing a UI FrameworkSimple

Mental ModelImmutable

Data

Page 40: Full Stack Scala

Choosing a UI FrameworkSimple

Mental ModelFunctional

programmingImmutable

Data

Page 41: Full Stack Scala

Choosing a UI FrameworkSimple

Mental Model

Mobile

Functionalprogramming

Immutable Data

Page 42: Full Stack Scala

Choosing a UI FrameworkSimple

Mental Model

Mobile

Functionalprogramming

Immutable Data

Isomorphism

Page 43: Full Stack Scala

Choosing a UI FrameworkSimple

Mental Model

CommunityMobile

Functionalprogramming

Immutable Data

Isomorphism

Page 44: Full Stack Scala

Choosing a UI FrameworkSimple

Mental Model

CommunityMobile

Functionalprogramming

Immutable Data

Isomorphism

Page 45: Full Stack Scala

What is React?• “A JavaScript library for building user interfaces” by

Facebook

• Focuses just on the UI• Uses virtual DOM• One-way data-flow

Page 46: Full Stack Scala

Frontend Overview

Page 47: Full Stack Scala

Frontend Overview

Router

Page 48: Full Stack Scala

Frontend Overview

Router

Page 49: Full Stack Scala

Frontend Overview

Router Flux Component

Page 50: Full Stack Scala

Frontend Overview

Router Flux Component

Page 51: Full Stack Scala

Frontend Overview

Router

Store

Flux Component

Page 52: Full Stack Scala

Frontend Overview

Router

Store

Flux Component

Page 53: Full Stack Scala

Frontend Overview

Router

Store

Flux Component

Rest Client

Page 54: Full Stack Scala

Frontend Overview

Router

Store

Flux Component

Rest Client

Page 55: Full Stack Scala

Frontend Overview

Router

Store

Flux Component

Rest Client

Page 56: Full Stack Scala

Frontend Overview

Router

Store

Flux Component

Rest Client

Page 57: Full Stack Scala

Frontend Overview

ComponentRouter

Store

Flux Component

Rest Client

Page 58: Full Stack Scala

Frontend Overview

ComponentRouter

Store

Flux Component

Rest Client

Page 59: Full Stack Scala

Scala.js with React

• Statically-typed wrapper around React• Fluent, builder API to create components• Well-implemented router (v2)

scalajs-react

Page 60: Full Stack Scala

Simple Mental Model

View

PropertiesState

Page 61: Full Stack Scala

Composition

Page 62: Full Stack Scala

Composition

Page 63: Full Stack Scala

Composition

Page 64: Full Stack Scala

Composition

Page 65: Full Stack Scala

Composition

Page 66: Full Stack Scala

Real World Composition

Page 67: Full Stack Scala

Real World Composition

Page 68: Full Stack Scala

Real World Composition

Page 69: Full Stack Scala

Mostly Immutable

ComponentRouter

Store

Flux Component

Rest Client

Page 70: Full Stack Scala

Taking advantage of immutability

def shouldComponentUpdate(scope: ScopeType, nextProps: P, nextState: S) = { scope.props != nextProps || scope.state != nextState}

Page 71: Full Stack Scala

Flux

Page 72: Full Stack Scala

Flux Componentobject ArtistRegistrationWrapper extends FluxComponent[String, ArtistEditDto](Seq(ArtistStore, InstrumentStore)) {

def onArtistChange(artist: ArtistEditDto): Unit = { ArtistUpdated(artist).dispatch() }

...

def element(props: String) = { ... div( ArtistRegistration( ArtistRegistrationProps( artist, allInstruments, onArtistChange, onArtistCoverPhotoChange, onArtistProfilsePhotoChange) ) ) }}

Page 73: Full Stack Scala

Component

object ArtistRegistration extends Component[ArtistRegistrationProps] {

def element(props: ArtistRegistrationProps): ReactTag = { div(…) }}

Page 74: Full Stack Scala

Responding to events

override def receive = { case ArtistUpdated(newValue) => artist = newValue emitChange() case ArtistSaved => save() emitChange() ...

Page 75: Full Stack Scala

No sweat undo/redotrait CompositionStore extends AbstractStore { val compositionStack = new UndoStack[Composition]() override def receive = { case NewComposition => compositionStack.clear() loaded() case LoadComposition(c) => compositionStack.clear() compositionStack.push(c) loaded() case UpdateComposition(c) => compositionStack.push(c) emitChange() case UndoComposition => compositionStack.undo() emitChange() case RedoComposition => compositionStack.redo() emitChange() ...}

Page 76: Full Stack Scala

Mobile: React Native

Page 77: Full Stack Scala

Mobile: React Native

https://facebook.github.io/react-native

Page 78: Full Stack Scala

Mobile: React Native

https://github.com/chandu0101/scalajs-react-native

https://facebook.github.io/react-native

Page 79: Full Stack Scala

Using external components

Page 80: Full Stack Scala

Bridging Native React Components• Problem:

• You got to use components developed in the wild

• Requires significant boilerplate to make it work from scalajs-react

• Solution: Some macro magic!

Page 81: Full Stack Scala

Bridging Native React Components• Problem:

• You got to use components developed in the wild

• Requires significant boilerplate to make it work from scalajs-react

• Solution: Some macro magic!

github.com/payalabs/scalajs-react-bridge

Page 82: Full Stack Scala

Example Bridge Component

case class TagsInput(id: js.UndefOr[String] = js.undefined, className: js.UndefOr[String] = js.undefined, ref: js.UndefOr[String] = js.undefined, key: js.UndefOr[Any] = js.undefined, defaultValue: js.UndefOr[Seq[String]] = js.undefined, value: js.UndefOr[Array[String]] = js.undefined, placeholder: js.UndefOr[String] = js.undefined, onChange: js.UndefOr[js.Array[String] => Unit] = js.undefined, validate: js.UndefOr[String => Boolean] = js.undefined, transform: js.UndefOr[String => String] = js.undefined) extends ReactBridgeComponent

Page 83: Full Stack Scala

Using TagsInput

div( TagsInput( defaultValue = Seq(“foo","bar"), onChange = printSequence _ ))

Page 84: Full Stack Scala

Using MDL in React• Problem:

• Components need to be “upgraded”

• Solution:• React wrapper component around a ReactTag• Upgrades element upon mounting• Implicits to avoid noise

Page 85: Full Stack Scala

Using MDL in React• Problem:

• Components need to be “upgraded”

• Solution:• React wrapper component around a ReactTag• Upgrades element upon mounting• Implicits to avoid noise

github.com/payalabs/scalajs-react-mdl

Page 86: Full Stack Scala

Example MDL Use

a(className := "mdl-button mdl-js-button mdl-button--raised mdl-button—colored mdl-js-ripple-effect", onClick --> saveAction())("Save").material

Page 87: Full Stack Scala

Example MDL Use

a(className := "mdl-button mdl-js-button mdl-button--raised mdl-button—colored mdl-js-ripple-effect", onClick --> saveAction())("Save").material

Page 88: Full Stack Scala

Things on the Horizon

• GraphQL?• Stitch?• Relay?• Falcor?

Page 89: Full Stack Scala

?Ramnivas Laddad

@ramnivas