Web application architecure: 
overview of techniques 
Ruslan Shevchenko. <ruslan@shevchenko.kiev.ua>! 
GoSave, Inc: http://www.gosave.com!
Themes 
❖ What are current architecture patterns, which ! 
❖ can be used! 
❖ can be reused ( in other languages or frameworks 
than origin)! 
! 
❖ Client/Service interaction. ! 
❖ Reactivity
What is in mainstream now ? 
❖ Sinatra-like frameworks! 
❖ Server:! 
❖ REST ! 
❖ Client: MVC! 
❖ yesterday: backbone! 
❖ today: angular! 
❖ tommorow: react.js + sumthing
shiny 
• http://shiny.rstudio.com/! 
• live example: http://shiny.rstudio.com/gallery/telephones-by-region.html! 
• R language! 
• 8 LOC : server! 
• 12 LOC: UI
shiny: UI.R 
library(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") 
) 
) 
))
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") 
}) 
})
Shiny: notes 
❖ DSL for HTML! 
❖ Reactive! 
❖ Websocket transport instead request/reply
Shiny: notes 
❖ DSL for HTML! 
❖ Reactive! 
❖ Websocket transport instead request/reply 
❖ Predefined UI skin (twitter bootstrap)! 
❖ Narrow applicability
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
max. enterprise: Java 
(Server-centric)! 
❖ dropwizard: https://dropwizard.github.io/dropwizard/! 
❖ spring: http://www.spring.io! 
❖ J2EE %-)
max. enterprise: java 
Relative 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(); 
}
max. enterprise: java 
Relative 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
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….
Client/Server API: One Language 
Many implementations 
• 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 … 
❖ Conway law, ! 
❖ Not one ‘ideal’ language for all
Client/Server API: IDL 
IDL == 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)
Client/Server: Fix REST 
REST without PUT 
RPC call = create event (i.e. POST /event )! 
seqence of events instead PUT 
CQRS = Command Query Responsibility 
Events State 
Query 
rdonly
Client/Server: Streaming 
Example: 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)
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!
Reactivity: client: Om 
https://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!
Reactivity: server 
Reactivity on server - more about C10K ! 
• http://www.reactivemanifesto.org/! 
• http://en.wikipedia.org/wiki/C10k_problem 
No blocking ….! 
event oriented …
Unreactive pseudocode: 1 
def 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) 
! 
}
Unreactive pseudocode: 1 
def 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) 
! 
}
Nonreactive: 1 
Client Application Server Database
Nonreactive: 1 / overload 
Client Application Server Database
Reactive code: 2 
latest Play: 
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) 
! 
}
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:
Non-reactive: 1 / overload 
Client Application Server Database
Reactive: 2 / overload 
Client Application Server Database
Reactive pseudocode: 3 
Imagine, we have reactive db driver: 
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) 
! 
} 
callback 
callback
Reactive: 3 / overload 
Client Application Server Database
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!
Server: reactivity 
Other computation models:! 
• Actors [Erlang, Scala Akka]! 
• Channels [Go, Closure core.async]! 
• Language reactive extensions! 
• [RxNet, RxJava, RxScala]
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
Web architecture: overview of techniques 
Thanks for attention.! 
! 
Ruslan Shevchenko, <ruslan@shevchenko.kiev.ua>! 
https://github.com/rssh! 
@rssh1! 
//this talk was bought to you by GoSave: http://www.gosave.com ;)!

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

  • 1.
    Web application architecure: overview of techniques Ruslan Shevchenko. <ruslan@shevchenko.kiev.ua>! GoSave, Inc: http://www.gosave.com!
  • 2.
    Themes ❖ Whatare current architecture patterns, which ! ❖ can be used! ❖ can be reused ( in other languages or frameworks than origin)! ! ❖ Client/Service interaction. ! ❖ Reactivity
  • 3.
    What is inmainstream now ? ❖ Sinatra-like frameworks! ❖ Server:! ❖ REST ! ❖ Client: MVC! ❖ yesterday: backbone! ❖ today: angular! ❖ tommorow: react.js + sumthing
  • 4.
    shiny • http://shiny.rstudio.com/! • live example: http://shiny.rstudio.com/gallery/telephones-by-region.html! • R language! • 8 LOC : server! • 12 LOC: UI
  • 5.
    shiny: UI.R library(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") ) ) ))
  • 6.
    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") }) })
  • 7.
    Shiny: notes ❖DSL for HTML! ❖ Reactive! ❖ Websocket transport instead request/reply
  • 8.
    Shiny: notes ❖DSL for HTML! ❖ Reactive! ❖ Websocket transport instead request/reply ❖ Predefined UI skin (twitter bootstrap)! ❖ Narrow applicability
  • 9.
    Conway law Organizationswhich 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
  • 10.
    max. enterprise: Java (Server-centric)! ❖ dropwizard: https://dropwizard.github.io/dropwizard/! ❖ spring: http://www.spring.io! ❖ J2EE %-)
  • 11.
    max. enterprise: java Relative 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(); }
  • 12.
    max. enterprise: java Relative 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
  • 13.
    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….
  • 14.
    Client/Server API: OneLanguage Many implementations • 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 … ❖ Conway law, ! ❖ Not one ‘ideal’ language for all
  • 15.
    Client/Server API: IDL IDL == 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)
  • 16.
    Client/Server: Fix REST REST without PUT RPC call = create event (i.e. POST /event )! seqence of events instead PUT CQRS = Command Query Responsibility Events State Query rdonly
  • 17.
    Client/Server: Streaming Example: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)
  • 18.
    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!
  • 19.
    Reactivity: client: Om https://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!
  • 20.
    Reactivity: server Reactivityon server - more about C10K ! • http://www.reactivemanifesto.org/! • http://en.wikipedia.org/wiki/C10k_problem No blocking ….! event oriented …
  • 21.
    Unreactive pseudocode: 1 def 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) ! }
  • 22.
    Unreactive pseudocode: 1 def 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) ! }
  • 23.
    Nonreactive: 1 ClientApplication Server Database
  • 24.
    Nonreactive: 1 /overload Client Application Server Database
  • 25.
    Reactive code: 2 latest Play: 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) ! }
  • 26.
    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:
  • 27.
    Non-reactive: 1 /overload Client Application Server Database
  • 28.
    Reactive: 2 /overload Client Application Server Database
  • 29.
    Reactive pseudocode: 3 Imagine, we have reactive db driver: 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) ! } callback callback
  • 30.
    Reactive: 3 /overload Client Application Server Database
  • 31.
    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!
  • 32.
    Server: reactivity Othercomputation models:! • Actors [Erlang, Scala Akka]! • Channels [Go, Closure core.async]! • Language reactive extensions! • [RxNet, RxJava, RxScala]
  • 33.
    Web architecture: overviewof 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
  • 34.
    Web architecture: overviewof techniques Thanks for attention.! ! Ruslan Shevchenko, <ruslan@shevchenko.kiev.ua>! https://github.com/rssh! @rssh1! //this talk was bought to you by GoSave: http://www.gosave.com ;)!