winning the application server arms race

37
Winning the Application Server Arms Race Using Smalltalk to Redene Web Development Avi Bryant

Upload: esug

Post on 22-Dec-2014

1.175 views

Category:

Technology


1 download

DESCRIPTION

Winning the Application Server Arms Race. Using Smalltalk to Redefine Web Development, Avi Bryant. (ESUG 2004, Koethen)

TRANSCRIPT

Page 1: Winning the Application Server Arms Race

Winning the Application Server Arms Race

Using Smalltalk to Redefine Web DevelopmentAvi Bryant

Page 2: Winning the Application Server Arms Race

Web apps: why bother?

“I’m more of the mind that HTML based apps suck.”

— James Robertson

Page 3: Winning the Application Server Arms Race

Web apps: why bother?

“One of the reasons to use Lisp in writing Web-based applications is that you ca! use Lisp. When you’re writing software that is only going to run on your own servers, you can use whatever language you want.”

— Paul Graham

Page 4: Winning the Application Server Arms Race

What is a web app?

“A collection of functions that take HTTP requests as input and produce HTTP responses as output.”

Page 5: Winning the Application Server Arms Race

What is a web app?

User with Web Browser

GET /foo?x=3...

Content-Type: text/html

...

/foo

Page 6: Winning the Application Server Arms Race

What is a web app?

User with Web Browser

GET /foo?x=3...

Content-Type: text/html

<a href=“/bar”...

/foo /bar /baz

Page 7: Winning the Application Server Arms Race

Client/server app

VisualWorks Client

GemStone Server

Page 8: Winning the Application Server Arms Race

Get Shipping Address

Get Billing

Address

GetPayment

Info

ShowConfirmation

Page 9: Winning the Application Server Arms Race

Get Shipping Address

Get Billing

Address

GetPayment

Info

ShowConfirmation

Cart info Cart infoShipping info

Cart infoShipping infoBilling info

Cart infoShipping infoBilling info

Payment info

Page 10: Winning the Application Server Arms Race

/shipping

User with Web Browser

cart

/billing

cartshipping

cartshipping

/payment

cartshippingbilling

cartshippingbilling

cartshippingbilling

payment

Page 11: Winning the Application Server Arms Race

User with Web Browser

cart cartshipping

cartshipping

cartshippingbilling

cartshippingbilling

cartshippingbilling

payment

formatting

processing

formatting

do stuff

processing

formatting

do stuffdo stuff

processing

Page 12: Winning the Application Server Arms Race

an App

a32cf6d

a Sessiona Sessiona Session

76ebc65...

User

GET /foo?sid=a32cf6d

... <a href=“/bar?sid=a32cf6d”>...

/foo

Page 13: Winning the Application Server Arms Race

an App

a32cf6d

a Sessiona Sessiona Session

76ebc65...

User

GET /bar?sid=a32cf6d

... <a href=“/baz?sid=a32cf6d”>...

/bar

Page 14: Winning the Application Server Arms Race

/shipping

User with Web Browser

/billing

sidshipping

/payment

sidbilling

sidpayment

a Sessionshipping billing

sid sid sid

sessions

Page 15: Winning the Application Server Arms Race

Book flight

Browse flights

Choose flight

Chooseseat

Why global session state is evil

Page 16: Winning the Application Server Arms Race

Book flight

Browse flights

Choose flight

Chooseseat

Choose flight

Chooseseat

Why global session state is evil

Page 17: Winning the Application Server Arms Race

Book flight

Browse flights

Choose flight

Chooseseat

Choose flight

Chooseseat

?

Why global session state is evil

Page 18: Winning the Application Server Arms Race

an App

a32cf6d

a Sessiona Sessiona Session

76ebc65...

a Component

f5c

a Component a Component

a21...

Page 19: Winning the Application Server Arms Race

... <input name=“page” value=“f5b”>...

a Session

a21a BrowseFlights

POST ... page=a21&flight=747

... <input name=“page” value=“a21”>...

User a ChooseFlight

f5b

Page 20: Winning the Application Server Arms Race

a Session

a21a BrowseFlights

POST ... page=a21&flight=525

User

... <input name=“page” value=“cc4”>...

a ChooseFlight

cc4f5b

a ChooseFlight

Page 21: Winning the Application Server Arms Race

WOComponentsubclass: #BillingAddressinstanceVariableNames: ‘ship bill’

response^ ‘<form ...’

processRequest: aRequestbill := self addressFrom: aRequest.

^ PaymentInfo newshippingAddress: ship;billingAddress: bill;yourself

Page 22: Winning the Application Server Arms Race

“Seaside is to most other Smalltalk web toolkits as Smalltalk is to most other OO languages, it’s as simple as that.”

— Cees de Groot

Page 23: Winning the Application Server Arms Race

WebObjects

• http://www.apple.com/webobjects/

• http://jakarta.apache.org/tapestry/

Page 24: Winning the Application Server Arms Race

WOComponentsubclass: #BillingAddressinstanceVariableNames: ‘ship bill’

processRequest: aRequestbill := self addressFrom: aRequest.

^ PaymentInfo newshippingAddress: ship;billingAddress: bill;yourself

Page 25: Winning the Application Server Arms Race

WOComponentsubclass: #BillingAddressinstanceVariableNames: ‘ship bill’

processRequest: aRequestbill := self addressFrom: aRequest.

^ PaymentInfo newshippingAddress: ship;billingAddress: bill;next: (ConfirmationPage new)yourself

Page 26: Winning the Application Server Arms Race

WOComponentsubclass: #BillingAddressinstanceVariableNames: ‘ship bill’

processRequest: aRequestbill := self addressFrom: aRequest.

^ nextshippingAddress: ship;billingAddress: bill;yourself

Page 27: Winning the Application Server Arms Race

checkoutProcess^ (ShippingAddress new next:

(BillingAddress new next:(PaymentInfo new next:

(ConfirmationPage new))))

Page 28: Winning the Application Server Arms Race

WOComponentsubclass: #BillingAddressinstanceVariableNames: ‘ship bill’

processRequest: aRequestbill := self addressFrom: aRequest.

^ next value: bill

“BillingAddress new next:[:bill |PaymentInfo newbillingAddress: bill;....]”

Page 29: Winning the Application Server Arms Race

checkoutProcess^ ShippingAddress new next:

[:ship |BillingAddress new next:[:bill |PaymentInfo new next:[:pay |ConfirmationPage newshippingAddress: ship;billingAddress: bill;paymentInfo: pay;yourself]

Page 30: Winning the Application Server Arms Race

checkoutProcess^ PaymentInfo new next:

[:pay |ShippingAdress new next:[:ship |BillingAddress new next:[:bill |ConfirmationPage newshippingAddress: ship;billingAddress: bill;paymentInfo: pay;yourself]

Page 31: Winning the Application Server Arms Race

“...programming language features do well (all other things being equal) when they eliminate either distant or dynamic state and replace it with either close or lexical state. The underlying point being that we may favour language features that facilitate copying and modifying small bits of code -- fragments which work in their new context -- as a fundamental programming activity.”

— Graydon Hoare

Page 32: Winning the Application Server Arms Race

checkoutProcess|pay ship bill|pay := self call: PaymentInfo new.ship := self call: ShippingAddress new.bill := self call: BillingAddress new.self call:(ConfirmationPage newshippingAddress: ship;billingAddress: bill;paymentInfo: pay)

Page 33: Winning the Application Server Arms Race

“We could write the code to say, if the user clicks on this link, go to the color selection page, and then come back here.... It made our software visibly more sophisticated than that of our competitors.”

— Paul Graham

Page 34: Winning the Application Server Arms Race

<form>Name: <input name="name"><br>Street: <input name="street"><br>City: <input name="city"><br>Country:<select name="country"><option value="CA">Canada</option><option value="US">US</option>

</select><br><input type="submit"></form>

aRequest( ‘name’->‘Avi’, ‘street’-> ‘123 W. 15th’‘city’->‘Vancouver’, ‘country’-> ‘CA’)

Page 35: Winning the Application Server Arms Race

renderOn: html

html form: [html label: ‘Name’.html textInputNamed: ‘name’; break.html label: ‘Street’.html textInputNamed: ‘street’; break.html label: ‘City’.html textInputNamed: ‘city’; break.html label: ‘Country’.html selectNamed: ‘country’ do: [html optionNamed: ‘CA’ label: ‘Canada’.html optionNamed: ‘US’ label: ‘US’.

]; break.html submitButton.

]

processRequest: aRequestname := aRequest at: ‘name’.street := aRequest at: ‘street’....

Page 36: Winning the Application Server Arms Race

renderOn: html

html form: [html label: ‘Name’.html textInputWithCallback: [:v | name := v]; break.html label: ‘Street’.html textInputWithCallback: [:v | street := v]; break.html label: ‘City’.html textInputWithCallback: [:v | city := v]; ‘city’; break.html label: ‘Country’.html selectFromList: self countries; break.html submitButtonWithAction: [self saveAddress].

]

Page 37: Winning the Application Server Arms Race

<form>Name: <input name="1"><br>Street: <input name="2"><br>City: <input name="3"><br>Country:<select name="4"><option value="5">Canada</option><option value="6">US</option>

</select><br><input type="submit" name="7" value="Submit"></form>

aRequest( ‘1’->‘Avi’,‘2’->...,

‘7’-> ‘Submit’)

aCallbackStore( ‘1’->[:v | name := v],

‘2’->...,‘7’->[self saveAddress])