34
Web application architecure: overview of techniques Ruslan Shevchenko. <[email protected]> GoSave, Inc: http://www.gosave.com

WebCamp: Developer Day: Архитектура Web-приложений: обзор современных решений - Руслан Шевченко

Embed Size (px)

DESCRIPTION

Архитектура Web-приложений: обзор современных решений Руслан Шевченко О разных подходах к проектированию web-приложений и трендах в этой области, включая как и относительный мейнстрим, так и экзотические решения, которые могут быть интересны в будущем.

Citation preview

Page 1: WebCamp: Developer Day: Архитектура Web-приложений: обзор современных решений - Руслан Шевченко

Web application architecure: overview of techniques Ruslan Shevchenko. <[email protected]>!

GoSave, Inc: http://www.gosave.com!

Page 2: WebCamp: Developer Day: Архитектура Web-приложений: обзор современных решений - Руслан Шевченко

Themes❖ What are current architecture patterns, which !

❖ can be used!

❖ can be reused ( in other languages or frameworks than origin)!

!

❖ Client/Service interaction. !

❖ Reactivity

Page 3: WebCamp: Developer Day: Архитектура Web-приложений: обзор современных решений - Руслан Шевченко

What is in mainstream now ?❖ Sinatra-like frameworks!❖ Server:!

❖ REST !❖ Client: MVC!

❖ yesterday: backbone!❖ today: angular!❖ tommorow: react.js + sumthing

Page 4: WebCamp: Developer Day: Архитектура Web-приложений: обзор современных решений - Руслан Шевченко

shiny• http://shiny.rstudio.com/!

• live example: http://shiny.rstudio.com/gallery/telephones-by-region.html!

• R language!

• 8 LOC : server!

• 12 LOC: UI

Page 5: WebCamp: Developer Day: Архитектура Web-приложений: обзор современных решений - Руслан Шевченко

shiny: UI.Rlibrary(shiny) library(datasets) !shinyUI( fluidPage( titlePanel("Telephones by region"), sidebarLayout( sidebarPanel( selectInput("region", "Region:", choices=colnames(WorldPhones)), hr(), helpText("Data from AT&T (1961) The World's Telephones.") ), mainPanel( plotOutput("phonePlot") ) ) ))

Page 6: WebCamp: Developer Day: Архитектура Web-приложений: обзор современных решений - Руслан Шевченко

shiny: Server.R

library(shiny) !# Rely on the 'WorldPhones' dataset in the datasets # package (which generally comes preloaded). library(datasets) !shinyServer(function(input, output) { output$phonePlot <- renderPlot({ barplot(WorldPhones[,input$region]*1000, main=input$region, ylab="Number of Telephones", xlab="Year") }) })

Page 7: WebCamp: Developer Day: Архитектура Web-приложений: обзор современных решений - Руслан Шевченко

Shiny: notes

❖ DSL for HTML!

❖ Reactive!

❖ Websocket transport instead request/reply

Page 8: WebCamp: Developer Day: Архитектура Web-приложений: обзор современных решений - Руслан Шевченко

Shiny: notes

❖ DSL for HTML!

❖ Reactive!

❖ Websocket transport instead request/reply

❖ Predefined UI skin (twitter bootstrap)!❖ Narrow applicability

Page 9: WebCamp: Developer Day: Архитектура Web-приложений: обзор современных решений - Руслан Шевченко

Conway law

Organizations which design systems ... are constrained to produce designs which are copies of the communication structures of these organizations ……! (Conway, 1968)!

Organization communication !structure

Software structure

Shiny <=> existence of data analysis department

Page 10: WebCamp: Developer Day: Архитектура Web-приложений: обзор современных решений - Руслан Шевченко

max. enterprise: Java

❖ dropwizard: https://dropwizard.github.io/dropwizard/!

❖ spring: http://www.spring.io!

❖ J2EE %-)

(Server-centric)!

Page 11: WebCamp: Developer Day: Архитектура Web-приложений: обзор современных решений - Руслан Шевченко

max. enterprise: javaRelative good and applicable:

@Path(“/users”) @GET @Produces({MediaType.APPLICATION_JSON}) @ApiOperation(nickname = "getUsers", value = "get list of users", httpMethod = "GET", response = UsersSortDTO.class, responseContainer = “List") public List<UserDTO> list(@ApiParam SelectorDTO selector) { CriteriaQuery<UserDTO> = … ………. return q.getResultList(); }

Page 12: WebCamp: Developer Day: Архитектура Web-приложений: обзор современных решений - Руслан Шевченко

max. enterprise: javaRelative good and applicable:

❖ Jersey: https://jersey.java.net/!

❖ request bind to method.!

❖ routing is set via annotations.!

❖ Jackson: https://github.com/FasterXML/jackson!

❖ annotation-based json serializer with good defaults!

❖ Swagger: https://helloreverb.com/developers/swagger

Page 13: WebCamp: Developer Day: Архитектура Web-приложений: обзор современных решений - Руслан Шевченко

Client/Server API issues.REST - is not fit for all

What we do with operations, other than CRUD over resources ?

❖ RPC on some language on top of javascript [?]!

❖ adopt IDL protocol [?]!

❖ fix REST [?]

Ideal solution yet not exists….

Page 14: WebCamp: Developer Day: Архитектура Web-приложений: обзор современных решений - Руслан Шевченко

Client/Server API: One Language

• Javascript (node.js) !• ClojureScript/ Clojure: http://clojure.org/!• Kotlin: http://kotlin-web-site.jetbrains.org/ !• Scala (!

• scala.js [http://www.scala-js.org/], !• jscala [ https://github.com/nau/jscala ] !

• R !• etc …

Many implementations

❖ Conway law, !❖ Not one ‘ideal’ language for all

Page 15: WebCamp: Developer Day: Архитектура Web-приложений: обзор современных решений - Руслан Шевченко

Client/Server API: IDLIDL == Interface Definition Language

struct ProfileInfo!{! 1: required string uid;! 2: optional string firstName;! 3: optional string middleName;! 4: optional string lastName;! 5: optional string email;! 6: optional string phone;! 7: optional string addrPostal;!}! !

service SelfCare!{! ProfileInfo getProfileInfo(required string authToken)! throws(OperationException)! …………

Implementations:!

thrift: http://thrift.apache.org/!

RSDL, WADL (xml-based)

Page 16: WebCamp: Developer Day: Архитектура Web-приложений: обзор современных решений - Руслан Шевченко

Client/Server: Fix RESTREST without PUT

RPC call = create event (i.e. POST /event )! seqence of events instead PUT

CQRS = Command Query Responsibility

Events State

Query

rdonly

Page 17: WebCamp: Developer Day: Архитектура Web-приложений: обзор современных решений - Руслан Шевченко

Client/Server: StreamingExample: sparkle. https://github.com/mighdoll/sparkle

Visualization of data stream, ! coming from server via websocket transport

Server (scala)

Client (javascript)

Server -> Client : Data Stream, !(reply to control messages)!

!Client -> Server: Control messages!

(subscribe/unsubscribe/transform)

Page 18: WebCamp: Developer Day: Архитектура Web-приложений: обзор современных решений - Руслан Шевченко

Reactivity: client.Shiny: one circuit with client and server.

More common: client-only reactive interactions, ! REST/RPC with server

❖ Angular.js [2/way binding]!

❖ React.js [1/way binding] !

❖ (model => view)!

❖ OM: https://github.com/swannodette/om!

❖ RFP!

❖ backon.js [ http://baconjs.github.io/], RxJs!

❖ ELM (language) http://elm-lang.org!

Page 19: WebCamp: Developer Day: Архитектура Web-приложений: обзор современных решений - Руслан Шевченко

Reactivity: client: Omhttps://github.com/swannodette/om

Clojure!!!

Application state = Tree, bound to clojure atom!!UI component state = path inside application state!!Use React.js for updating UI from change in application state!

Page 20: WebCamp: Developer Day: Архитектура Web-приложений: обзор современных решений - Руслан Шевченко

Reactivity: serverReactivity on server - more about C10K !

• http://www.reactivemanifesto.org/!

• http://en.wikipedia.org/wiki/C10k_problem

No blocking ….!event oriented …

Page 21: WebCamp: Developer Day: Архитектура Web-приложений: обзор современных решений - Руслан Шевченко

Unreactive pseudocode: 1def listUsers(r: Request): RequestResult = listForm.bind(request){ ! success(form) => Ok (ToJson( users.filter(_.name contains form.q). page(form.offset,form.limit) ) ), ! failure(f,message, ex) => Error(403, message) !}

Page 22: WebCamp: Developer Day: Архитектура Web-приложений: обзор современных решений - Руслан Шевченко

Unreactive pseudocode: 1def listUsers(r: Request): RequestResult = listForm.bind(request){ ! success(form) => Ok (ToJson( users.filter(_.name contains form.q). page(form.offset,form.limit) ) ), ! failure(f,message, ex) => Error(403, message) !}

Page 23: WebCamp: Developer Day: Архитектура Web-приложений: обзор современных решений - Руслан Шевченко

Nonreactive: 1

Application ServerClient Database

Page 24: WebCamp: Developer Day: Архитектура Web-приложений: обзор современных решений - Руслан Шевченко

Nonreactive: 1 / overload

Application ServerClient Database

Page 25: WebCamp: Developer Day: Архитектура Web-приложений: обзор современных решений - Руслан Шевченко

Reactive code: 2

def listUsers = Action { request => listForm.bind(request){ ! success(form) => Ok (ToJson( users.filter(_.name contains form.q). page(form.offset,form.limit) ) ), ! failure(f,message, ex) => Error(403, message) !}

latest Play:

Page 26: WebCamp: Developer Day: Архитектура Web-приложений: обзор современных решений - Руслан Шевченко

Reactive code: 2

def listUsers = Action { request => listForm.bind(request){ ! success(form) => Ok (ToJson( users.filter(_.name contains form.q). page(form.offset,form.limit) ) ), ! failure(f,message, ex) => Error(403, message) !}

callback

latest Play:

Page 27: WebCamp: Developer Day: Архитектура Web-приложений: обзор современных решений - Руслан Шевченко

Non-reactive: 1 / overload

Application ServerClient Database

Page 28: WebCamp: Developer Day: Архитектура Web-приложений: обзор современных решений - Руслан Шевченко

Reactive: 2 / overload

Application ServerClient Database

Page 29: WebCamp: Developer Day: Архитектура Web-приложений: обзор современных решений - Руслан Шевченко

Reactive pseudocode: 3

def listUsers = Action { request => listForm.bind(request){ ! success(form) => Ok ( db.query( users.filter(_.name contains form.q). page(form.offset,form.limit) ) map ( x => ToJson(x) ) ), ! failure(f,message, ex) => Error(403, message) !}

Imagine, we have reactive db driver:callback

callback

Page 30: WebCamp: Developer Day: Архитектура Web-приложений: обзор современных решений - Руслан Шевченко

Reactive: 3 / overload

Application ServerClient Database

Page 31: WebCamp: Developer Day: Архитектура Web-приложений: обзор современных решений - Руслан Шевченко

Server: reactivity

• 2 callbacks instead sequential code!• (welcome to callback hell ?)!• functional programming is really needed!

• Infrastructure is not mature yet.!• reactive-mongo, reactive-postgres,!• but we have no reactivity suport in jdbc!

Page 32: WebCamp: Developer Day: Архитектура Web-приложений: обзор современных решений - Руслан Шевченко

Server: reactivity

Other computation models:!• Actors [Erlang, Scala Akka]!• Channels [Go, Closure core.async]!• Language reactive extensions!

• [RxNet, RxJava, RxScala]

Page 33: WebCamp: Developer Day: Архитектура Web-приложений: обзор современных решений - Руслан Шевченко

Web architecture: overview of techniques

❖ Can’t say that we have some ‘Canonical ideal architecture’.!

❖ Non-ideal techniques are still interesting.!

❖ Invention/Reinvention cycle => !

❖ Hope we will see something new!

❖ Take care

Page 34: WebCamp: Developer Day: Архитектура Web-приложений: обзор современных решений - Руслан Шевченко

Web architecture: overview of techniques

Thanks for attention.!

!

Ruslan Shevchenko, <[email protected]>!

https://github.com/rssh!

@rssh1!

//this talk was bought to you by GoSave: http://www.gosave.com ;)!