Download - Voyager avec play scala
![Page 1: Voyager avec play scala](https://reader034.vdocument.in/reader034/viewer/2022051314/555cb69dd8b42ab2358b58b4/html5/thumbnails/1.jpg)
Voyager avec Play 2
Nicolas [email protected]
@nmartignoleScala.IO - 24/25 octobre 2013, Paris
samedi 26 octobre 13
![Page 2: Voyager avec play scala](https://reader034.vdocument.in/reader034/viewer/2022051314/555cb69dd8b42ab2358b58b4/html5/thumbnails/2.jpg)
Votre plan de vol
ZapTravel
WhatWhyHow
samedi 26 octobre 13
![Page 3: Voyager avec play scala](https://reader034.vdocument.in/reader034/viewer/2022051314/555cb69dd8b42ab2358b58b4/html5/thumbnails/3.jpg)
Avant de commencer...
Current status
samedi 26 octobre 13
![Page 4: Voyager avec play scala](https://reader034.vdocument.in/reader034/viewer/2022051314/555cb69dd8b42ab2358b58b4/html5/thumbnails/4.jpg)
ZapTravel
samedi 26 octobre 13
![Page 5: Voyager avec play scala](https://reader034.vdocument.in/reader034/viewer/2022051314/555cb69dd8b42ab2358b58b4/html5/thumbnails/5.jpg)
We search destinations & dates, then find the best price, hotel and
transport, so you don’t need to
samedi 26 octobre 13
![Page 6: Voyager avec play scala](https://reader034.vdocument.in/reader034/viewer/2022051314/555cb69dd8b42ab2358b58b4/html5/thumbnails/6.jpg)
We search destinations & dates, then find the best price, hotel and
transport, so you don’t need to
filter, map, reduce
samedi 26 octobre 13
![Page 7: Voyager avec play scala](https://reader034.vdocument.in/reader034/viewer/2022051314/555cb69dd8b42ab2358b58b4/html5/thumbnails/7.jpg)
ZapTravel
samedi 26 octobre 13
![Page 8: Voyager avec play scala](https://reader034.vdocument.in/reader034/viewer/2022051314/555cb69dd8b42ab2358b58b4/html5/thumbnails/8.jpg)
samedi 26 octobre 13
![Page 9: Voyager avec play scala](https://reader034.vdocument.in/reader034/viewer/2022051314/555cb69dd8b42ab2358b58b4/html5/thumbnails/9.jpg)
samedi 26 octobre 13
![Page 10: Voyager avec play scala](https://reader034.vdocument.in/reader034/viewer/2022051314/555cb69dd8b42ab2358b58b4/html5/thumbnails/10.jpg)
samedi 26 octobre 13
![Page 11: Voyager avec play scala](https://reader034.vdocument.in/reader034/viewer/2022051314/555cb69dd8b42ab2358b58b4/html5/thumbnails/11.jpg)
MobileAPI REST
samedi 26 octobre 13
![Page 12: Voyager avec play scala](https://reader034.vdocument.in/reader034/viewer/2022051314/555cb69dd8b42ab2358b58b4/html5/thumbnails/12.jpg)
samedi 26 octobre 13
![Page 13: Voyager avec play scala](https://reader034.vdocument.in/reader034/viewer/2022051314/555cb69dd8b42ab2358b58b4/html5/thumbnails/13.jpg)
samedi 26 octobre 13
![Page 14: Voyager avec play scala](https://reader034.vdocument.in/reader034/viewer/2022051314/555cb69dd8b42ab2358b58b4/html5/thumbnails/14.jpg)
samedi 26 octobre 13
![Page 15: Voyager avec play scala](https://reader034.vdocument.in/reader034/viewer/2022051314/555cb69dd8b42ab2358b58b4/html5/thumbnails/15.jpg)
samedi 26 octobre 13
![Page 16: Voyager avec play scala](https://reader034.vdocument.in/reader034/viewer/2022051314/555cb69dd8b42ab2358b58b4/html5/thumbnails/16.jpg)
RomanceShow medeals
samedi 26 octobre 13
![Page 17: Voyager avec play scala](https://reader034.vdocument.in/reader034/viewer/2022051314/555cb69dd8b42ab2358b58b4/html5/thumbnails/17.jpg)
FamilyShow medeals
samedi 26 octobre 13
![Page 18: Voyager avec play scala](https://reader034.vdocument.in/reader034/viewer/2022051314/555cb69dd8b42ab2358b58b4/html5/thumbnails/18.jpg)
samedi 26 octobre 13
![Page 19: Voyager avec play scala](https://reader034.vdocument.in/reader034/viewer/2022051314/555cb69dd8b42ab2358b58b4/html5/thumbnails/19.jpg)
</zaptravel>samedi 26 octobre 13
![Page 20: Voyager avec play scala](https://reader034.vdocument.in/reader034/viewer/2022051314/555cb69dd8b42ab2358b58b4/html5/thumbnails/20.jpg)
“There are known knowns; there are things we know that we know.There are known unknowns; that is to say, there are things that we now know we don't know.But there are also unknown unknowns – there are things we do not know we don't know.
”—United States Secretary of Defense, Donald Rumsfeld
samedi 26 octobre 13
![Page 21: Voyager avec play scala](https://reader034.vdocument.in/reader034/viewer/2022051314/555cb69dd8b42ab2358b58b4/html5/thumbnails/21.jpg)
Aware
KnowDon’t know
Not aware
samedi 26 octobre 13
![Page 22: Voyager avec play scala](https://reader034.vdocument.in/reader034/viewer/2022051314/555cb69dd8b42ab2358b58b4/html5/thumbnails/22.jpg)
Aware
KnowDon’t know
Not aware
samedi 26 octobre 13
![Page 23: Voyager avec play scala](https://reader034.vdocument.in/reader034/viewer/2022051314/555cb69dd8b42ab2358b58b4/html5/thumbnails/23.jpg)
Quelques chiffres
• 159 000 hôtels
• 1383 destinations
• 840 000 transports (avions/trains)
• 1.4To images sur S3
• 20600 prix chambres hôtels
samedi 26 octobre 13
![Page 24: Voyager avec play scala](https://reader034.vdocument.in/reader034/viewer/2022051314/555cb69dd8b42ab2358b58b4/html5/thumbnails/24.jpg)
redis 127.0.0.1:6379> hlen Hotel:Content:Short(integer) 158 041
samedi 26 octobre 13
![Page 25: Voyager avec play scala](https://reader034.vdocument.in/reader034/viewer/2022051314/555cb69dd8b42ab2358b58b4/html5/thumbnails/25.jpg)
Ce que je savais
samedi 26 octobre 13
![Page 26: Voyager avec play scala](https://reader034.vdocument.in/reader034/viewer/2022051314/555cb69dd8b42ab2358b58b4/html5/thumbnails/26.jpg)
Ce que je savais
• Play! Framework
samedi 26 octobre 13
![Page 27: Voyager avec play scala](https://reader034.vdocument.in/reader034/viewer/2022051314/555cb69dd8b42ab2358b58b4/html5/thumbnails/27.jpg)
Ce que je savais
• Play! Framework
•Web development
samedi 26 octobre 13
![Page 28: Voyager avec play scala](https://reader034.vdocument.in/reader034/viewer/2022051314/555cb69dd8b42ab2358b58b4/html5/thumbnails/28.jpg)
Ce que je savais
• Play! Framework
•Web development
•Hiring and training developers
samedi 26 octobre 13
![Page 29: Voyager avec play scala](https://reader034.vdocument.in/reader034/viewer/2022051314/555cb69dd8b42ab2358b58b4/html5/thumbnails/29.jpg)
Ce que je savais
• Play! Framework
•Web development
•Hiring and training developers
• Kiss-ass project managment
samedi 26 octobre 13
![Page 30: Voyager avec play scala](https://reader034.vdocument.in/reader034/viewer/2022051314/555cb69dd8b42ab2358b58b4/html5/thumbnails/30.jpg)
EquipePlay2 ScalaHTML CSS ScalaJavaZe Boss
samedi 26 octobre 13
![Page 31: Voyager avec play scala](https://reader034.vdocument.in/reader034/viewer/2022051314/555cb69dd8b42ab2358b58b4/html5/thumbnails/31.jpg)
Equipe
0
1,25
2,5
3,75
5
Mai 2012 Ete 2012 Sept 2012 Oct 2012 Nov 2012 Jan 2013 Oct 2013
Play2 ScalaHTML CSS ScalaJavaZe Boss
samedi 26 octobre 13
![Page 32: Voyager avec play scala](https://reader034.vdocument.in/reader034/viewer/2022051314/555cb69dd8b42ab2358b58b4/html5/thumbnails/32.jpg)
samedi 26 octobre 13
![Page 33: Voyager avec play scala](https://reader034.vdocument.in/reader034/viewer/2022051314/555cb69dd8b42ab2358b58b4/html5/thumbnails/33.jpg)
Comment apprendre Scala
(et désapprendre Java)
samedi 26 octobre 13
![Page 34: Voyager avec play scala](https://reader034.vdocument.in/reader034/viewer/2022051314/555cb69dd8b42ab2358b58b4/html5/thumbnails/34.jpg)
Scala et Zaptravel
• Scala => recrutement
• Facile à apprendre
• Scala c’est simple
samedi 26 octobre 13
![Page 35: Voyager avec play scala](https://reader034.vdocument.in/reader034/viewer/2022051314/555cb69dd8b42ab2358b58b4/html5/thumbnails/35.jpg)
Ah tu fais du Scala
samedi 26 octobre 13
![Page 36: Voyager avec play scala](https://reader034.vdocument.in/reader034/viewer/2022051314/555cb69dd8b42ab2358b58b4/html5/thumbnails/36.jpg)
Paradigme objet ET fonctionnel
http://parleys.com/p/51c1994ae4b0d38b54f4621b
samedi 26 octobre 13
![Page 37: Voyager avec play scala](https://reader034.vdocument.in/reader034/viewer/2022051314/555cb69dd8b42ab2358b58b4/html5/thumbnails/37.jpg)
Ce que j’ai évité
- 18
samedi 26 octobre 13
![Page 38: Voyager avec play scala](https://reader034.vdocument.in/reader034/viewer/2022051314/555cb69dd8b42ab2358b58b4/html5/thumbnails/38.jpg)
SBT
samedi 26 octobre 13
![Page 39: Voyager avec play scala](https://reader034.vdocument.in/reader034/viewer/2022051314/555cb69dd8b42ab2358b58b4/html5/thumbnails/39.jpg)
SBT
ScalaZ
samedi 26 octobre 13
![Page 40: Voyager avec play scala](https://reader034.vdocument.in/reader034/viewer/2022051314/555cb69dd8b42ab2358b58b4/html5/thumbnails/40.jpg)
Les choses que je ne savais pas
• Faut être gonflé
• Communauté
• Parallélisme, Reactivité
• Play2/Scala/Redis en PROD ???
• SEO
• JSON+Redis
• Typesafe / refactoring
samedi 26 octobre 13
![Page 41: Voyager avec play scala](https://reader034.vdocument.in/reader034/viewer/2022051314/555cb69dd8b42ab2358b58b4/html5/thumbnails/41.jpg)
samedi 26 octobre 13
![Page 42: Voyager avec play scala](https://reader034.vdocument.in/reader034/viewer/2022051314/555cb69dd8b42ab2358b58b4/html5/thumbnails/42.jpg)
Communauté Scala
Place de Scala, la communauté, par rapport à Java
samedi 26 octobre 13
![Page 43: Voyager avec play scala](https://reader034.vdocument.in/reader034/viewer/2022051314/555cb69dd8b42ab2358b58b4/html5/thumbnails/43.jpg)
94 516 VUEs
Scala Days 2013 on parleys.com
samedi 26 octobre 13
![Page 44: Voyager avec play scala](https://reader034.vdocument.in/reader034/viewer/2022051314/555cb69dd8b42ab2358b58b4/html5/thumbnails/44.jpg)
Parallélisme et concurrence
It’s the web, stupid
Response[HTML] = Fx(Request)
samedi 26 octobre 13
![Page 45: Voyager avec play scala](https://reader034.vdocument.in/reader034/viewer/2022051314/555cb69dd8b42ab2358b58b4/html5/thumbnails/45.jpg)
Typesafe
•HTML template•routes•config•LESS
samedi 26 octobre 13
![Page 46: Voyager avec play scala](https://reader034.vdocument.in/reader034/viewer/2022051314/555cb69dd8b42ab2358b58b4/html5/thumbnails/46.jpg)
Play2 -> ReactiveReactive In Practice
samedi 26 octobre 13
![Page 47: Voyager avec play scala](https://reader034.vdocument.in/reader034/viewer/2022051314/555cb69dd8b42ab2358b58b4/html5/thumbnails/47.jpg)
Play2 -> ReactiveReactive In Practice
samedi 26 octobre 13
![Page 48: Voyager avec play scala](https://reader034.vdocument.in/reader034/viewer/2022051314/555cb69dd8b42ab2358b58b4/html5/thumbnails/48.jpg)
août - sept 2012R.I.P
Iteratee, Enumeratee and Enumerator on Zaptravel
samedi 26 octobre 13
![Page 49: Voyager avec play scala](https://reader034.vdocument.in/reader034/viewer/2022051314/555cb69dd8b42ab2358b58b4/html5/thumbnails/49.jpg)
BusinessExceptionIteratee/Enumeratee/Enumerator c’est cool, mais nous n’en n’avons pas besoin pour le moment.
samedi 26 octobre 13
![Page 50: Voyager avec play scala](https://reader034.vdocument.in/reader034/viewer/2022051314/555cb69dd8b42ab2358b58b4/html5/thumbnails/50.jpg)
/**
* Server sent event streaming controller.
* Date: 06/08/12
* Time: 12:16
*/
object Streaming extends Controller {
// Streaming using server sent event
def stream(requestId: String) = Action {
// Define an implicit EventNameExtractor wich extract the "event" name from the Json event so that the EventSource() sets
the event in the message
implicit val eventNameExtractor: EventNameExtractor[JsValue]=EventNameExtractor[JsValue](eventName = (zepEvent)=>zepEvent.\
("event").asOpt[String])
// Streams.events is a composition of HotelPrice and AirfarePrice.
Ok.feed(Streams.events(requestId) &> EventSource()).as("text/event-stream")
}
implicit val eventNameExtractor: EventNameExtractor[JsValue] =EventNameExtractor[JsValue](eventName = (zepEvent)=>zepEvent.\("event").asOpt[String])
samedi 26 octobre 13
![Page 51: Voyager avec play scala](https://reader034.vdocument.in/reader034/viewer/2022051314/555cb69dd8b42ab2358b58b4/html5/thumbnails/51.jpg)
Akkafaukon
samedi 26 octobre 13
![Page 52: Voyager avec play scala](https://reader034.vdocument.in/reader034/viewer/2022051314/555cb69dd8b42ab2358b58b4/html5/thumbnails/52.jpg)
Akka•Cron Jobs
• Emails (Mailjet/Mailchimp)
• ElasticSearch index (proto)
• Sitemap
•Generate content (R.I.P.)
samedi 26 octobre 13
![Page 53: Voyager avec play scala](https://reader034.vdocument.in/reader034/viewer/2022051314/555cb69dd8b42ab2358b58b4/html5/thumbnails/53.jpg)
Akka
samedi 26 octobre 13
![Page 54: Voyager avec play scala](https://reader034.vdocument.in/reader034/viewer/2022051314/555cb69dd8b42ab2358b58b4/html5/thumbnails/54.jpg)
Dev ?
EC2 m2.2xlarge
Play2
Redis
RedisPrices
Prix Hotels, Avions,Voitures, Trains, Rating Hotel
27GB870k obj
EC2 m2.xlarge
Lieux, Destinations,Contenu, Routage, URLs, Places, Tags,
Webuser
1.2 GB450k obj
RedisStatic
slave-of
read-only
read/write
S3
samedi 26 octobre 13
![Page 55: Voyager avec play scala](https://reader034.vdocument.in/reader034/viewer/2022051314/555cb69dd8b42ab2358b58b4/html5/thumbnails/55.jpg)
Prod ?
Cloudfront ELBRoute53
EC2 c1.medium
wwwredis prices
EC2 m2.2xlarge
redis static
EC2 m2.xlarge
SimpleDB
logs
CloudWatch
S3
redis backup
samedi 26 octobre 13
![Page 56: Voyager avec play scala](https://reader034.vdocument.in/reader034/viewer/2022051314/555cb69dd8b42ab2358b58b4/html5/thumbnails/56.jpg)
Play2 + AWS
samedi 26 octobre 13
![Page 57: Voyager avec play scala](https://reader034.vdocument.in/reader034/viewer/2022051314/555cb69dd8b42ab2358b58b4/html5/thumbnails/57.jpg)
Idéal : c1.medium
2 vCPUs1.7 GB mémoire
samedi 26 octobre 13
![Page 58: Voyager avec play scala](https://reader034.vdocument.in/reader034/viewer/2022051314/555cb69dd8b42ab2358b58b4/html5/thumbnails/58.jpg)
Redis
samedi 26 octobre 13
![Page 59: Voyager avec play scala](https://reader034.vdocument.in/reader034/viewer/2022051314/555cb69dd8b42ab2358b58b4/html5/thumbnails/59.jpg)
Ce qu’il faut retenir
• IaaS versus PaaS pour Zaptravel
2300 USD / mois
samedi 26 octobre 13
![Page 60: Voyager avec play scala](https://reader034.vdocument.in/reader034/viewer/2022051314/555cb69dd8b42ab2358b58b4/html5/thumbnails/60.jpg)
Boarding...
samedi 26 octobre 13
![Page 61: Voyager avec play scala](https://reader034.vdocument.in/reader034/viewer/2022051314/555cb69dd8b42ab2358b58b4/html5/thumbnails/61.jpg)
Des cas d’usages
samedi 26 octobre 13
![Page 62: Voyager avec play scala](https://reader034.vdocument.in/reader034/viewer/2022051314/555cb69dd8b42ab2358b58b4/html5/thumbnails/62.jpg)
Fonctionnalités
samedi 26 octobre 13
![Page 63: Voyager avec play scala](https://reader034.vdocument.in/reader034/viewer/2022051314/555cb69dd8b42ab2358b58b4/html5/thumbnails/63.jpg)
Fonctionnalités• API REST
samedi 26 octobre 13
![Page 64: Voyager avec play scala](https://reader034.vdocument.in/reader034/viewer/2022051314/555cb69dd8b42ab2358b58b4/html5/thumbnails/64.jpg)
Fonctionnalités• API REST
samedi 26 octobre 13
![Page 65: Voyager avec play scala](https://reader034.vdocument.in/reader034/viewer/2022051314/555cb69dd8b42ab2358b58b4/html5/thumbnails/65.jpg)
Fonctionnalités• API REST
• Weather
samedi 26 octobre 13
![Page 66: Voyager avec play scala](https://reader034.vdocument.in/reader034/viewer/2022051314/555cb69dd8b42ab2358b58b4/html5/thumbnails/66.jpg)
Fonctionnalités• API REST
• Weather
• GeoIP
samedi 26 octobre 13
![Page 67: Voyager avec play scala](https://reader034.vdocument.in/reader034/viewer/2022051314/555cb69dd8b42ab2358b58b4/html5/thumbnails/67.jpg)
Fonctionnalités• API REST
• Weather
• GeoIP
• Semantic Search
samedi 26 octobre 13
![Page 68: Voyager avec play scala](https://reader034.vdocument.in/reader034/viewer/2022051314/555cb69dd8b42ab2358b58b4/html5/thumbnails/68.jpg)
Fonctionnalités• API REST
• Weather
• GeoIP
• Semantic Search
• Cache Redis
samedi 26 octobre 13
![Page 69: Voyager avec play scala](https://reader034.vdocument.in/reader034/viewer/2022051314/555cb69dd8b42ab2358b58b4/html5/thumbnails/69.jpg)
Fonctionnalités• API REST
• Weather
• GeoIP
• Semantic Search
• Cache Redis
• Mobile Web version
samedi 26 octobre 13
![Page 70: Voyager avec play scala](https://reader034.vdocument.in/reader034/viewer/2022051314/555cb69dd8b42ab2358b58b4/html5/thumbnails/70.jpg)
Fonctionnalités• API REST
• Weather
• GeoIP
• Semantic Search
• Cache Redis
• Mobile Web version
• Authentification
samedi 26 octobre 13
![Page 71: Voyager avec play scala](https://reader034.vdocument.in/reader034/viewer/2022051314/555cb69dd8b42ab2358b58b4/html5/thumbnails/71.jpg)
Fonctionnalités• API REST
• Weather
• GeoIP
• Semantic Search
• Cache Redis
• Mobile Web version
• Authentification
• Statistiques/Parcours visiteur
samedi 26 octobre 13
![Page 72: Voyager avec play scala](https://reader034.vdocument.in/reader034/viewer/2022051314/555cb69dd8b42ab2358b58b4/html5/thumbnails/72.jpg)
Fonctionnalités• API REST
• Weather
• GeoIP
• Semantic Search
• Cache Redis
• Mobile Web version
• Authentification
• Statistiques/Parcours visiteur
samedi 26 octobre 13
![Page 73: Voyager avec play scala](https://reader034.vdocument.in/reader034/viewer/2022051314/555cb69dd8b42ab2358b58b4/html5/thumbnails/73.jpg)
Quelques exemples
ZapTravel
samedi 26 octobre 13
![Page 74: Voyager avec play scala](https://reader034.vdocument.in/reader034/viewer/2022051314/555cb69dd8b42ab2358b58b4/html5/thumbnails/74.jpg)
Charger une donnée venant de Redis
ZapTravel
samedi 26 octobre 13
![Page 75: Voyager avec play scala](https://reader034.vdocument.in/reader034/viewer/2022051314/555cb69dd8b42ab2358b58b4/html5/thumbnails/75.jpg)
Architecture
LB
Web
Web
Web
HTTPHTTPS
RedisAir/Hotel/Cars/Ac
RedisResa/Users
RedisWeb Content
ZapTravel
samedi 26 octobre 13
![Page 76: Voyager avec play scala](https://reader034.vdocument.in/reader034/viewer/2022051314/555cb69dd8b42ab2358b58b4/html5/thumbnails/76.jpg)
Architecture
LB
Web
Web
Web
HTTPHTTPS
RedisAir/Hotel/Cars/Ac
RedisResa/Users
RedisWeb Content
Web
redis
ZapTravel
samedi 26 octobre 13
![Page 77: Voyager avec play scala](https://reader034.vdocument.in/reader034/viewer/2022051314/555cb69dd8b42ab2358b58b4/html5/thumbnails/77.jpg)
Cas d’usage
ZapTravel
Donne moi le label qui correspond à originId =380
samedi 26 octobre 13
![Page 78: Voyager avec play scala](https://reader034.vdocument.in/reader034/viewer/2022051314/555cb69dd8b42ab2358b58b4/html5/thumbnails/78.jpg)
Cas d’usage
ZapTravel
Donne moi le label qui correspond à originId =380
def getSlug(originId: Long): Option[String] = Redis.pool.withClient { client => Option(client.hget("Url:From:Rev", originId.toString))}
samedi 26 octobre 13
![Page 79: Voyager avec play scala](https://reader034.vdocument.in/reader034/viewer/2022051314/555cb69dd8b42ab2358b58b4/html5/thumbnails/79.jpg)
Cas d’usage
ZapTravel
Donne moi le label qui correspond à originId =380
def getSlug(originId: Long): Option[String] = Redis.pool.withClient { client => Option(client.hget("Url:From:Rev", originId.toString))}
samedi 26 octobre 13
![Page 80: Voyager avec play scala](https://reader034.vdocument.in/reader034/viewer/2022051314/555cb69dd8b42ab2358b58b4/html5/thumbnails/80.jpg)
Cas d’usage
ZapTravel
Donne moi le label qui correspond à originId =380
def getSlug(originId: Long): Option[String] = Redis.pool.withClient { client => Option(client.hget("Url:From:Rev", originId.toString))}
Driver Sedis https://github.com/pk11/sedissamedi 26 octobre 13
![Page 81: Voyager avec play scala](https://reader034.vdocument.in/reader034/viewer/2022051314/555cb69dd8b42ab2358b58b4/html5/thumbnails/81.jpg)
Un mot sur les Tests
samedi 26 octobre 13
![Page 82: Voyager avec play scala](https://reader034.vdocument.in/reader034/viewer/2022051314/555cb69dd8b42ab2358b58b4/html5/thumbnails/82.jpg)
https://gist.github.com/nicmarti/5064048
package models import org.specs2.mutable._ import play.api.test._import play.api.test.Helpers._ class OriginSpecs extends Specification { "An Origin" should { "returns the slug for a valid origin" in { running(FakeApplication()) { Origin.getSlug(380) mustEqual Some("from-london") Origin.getSlug(1) mustEqual Some("from-paris") Origin.getSlug(-9999) mustEqual None } } }}
samedi 26 octobre 13
![Page 83: Voyager avec play scala](https://reader034.vdocument.in/reader034/viewer/2022051314/555cb69dd8b42ab2358b58b4/html5/thumbnails/83.jpg)
Charger un objet
ZapTravel
Charge moi un Objet «Londres»
samedi 26 octobre 13
![Page 84: Voyager avec play scala](https://reader034.vdocument.in/reader034/viewer/2022051314/555cb69dd8b42ab2358b58b4/html5/thumbnails/84.jpg)
Charger un objet Origin
ZapTravel
def getOrigin(originId: Long): Option[Origin] = Redis.pool.withClient { client => Option(client.hget("Url:From:Rev", originId.toString)).map{ slug=> Option(client.hget("Places:Place:"+originId, "display").map { .... ... } }}
1) charger from-london
samedi 26 octobre 13
![Page 85: Voyager avec play scala](https://reader034.vdocument.in/reader034/viewer/2022051314/555cb69dd8b42ab2358b58b4/html5/thumbnails/85.jpg)
Code smells
ZapTravel
2) charger display...
def getOrigin(originId: Long): Option[Origin] = Redis.pool.withClient { client => Option(client.hget("Url:From:Rev", originId.toString)).map{ slug=> Option(client.hget("Places:Place:"+originId, "display").map{ .... ... } }}
samedi 26 octobre 13
![Page 86: Voyager avec play scala](https://reader034.vdocument.in/reader034/viewer/2022051314/555cb69dd8b42ab2358b58b4/html5/thumbnails/86.jpg)
Cas d’usage
ZapTravel
def getOrigin(originId: Long): Option[Origin] = Redis.pool.withClient { client => for(slug<-Option(client.hget("Url:From:Rev", originId.toString)); display<-Option(client.hget("Places:Place:"+originId,"display") )) yield Origin(originId,display,slug)
}}
2) charger display...
for-comprehensionhttps://gist.github.com/nicmarti/5064066
samedi 26 octobre 13
![Page 87: Voyager avec play scala](https://reader034.vdocument.in/reader034/viewer/2022051314/555cb69dd8b42ab2358b58b4/html5/thumbnails/87.jpg)
La Tour Eiffel
ZapTravel
1. Charger du JSON à partir de Redis2. Interpréter et retourner un objet PointOfInterest
samedi 26 octobre 13
![Page 88: Voyager avec play scala](https://reader034.vdocument.in/reader034/viewer/2022051314/555cb69dd8b42ab2358b58b4/html5/thumbnails/88.jpg)
{"name":"Eiffel Tower","address":"","latitude":"48.8582493546","longitude":"2.2945117950","website":"www.tour-eiffel.fr","rank":3,"photo":{"r":"eiffel-tower-paris-france","k":"6b56","e":"jpg","w":2406,"h":1600,"a":"Mirari Erdoiza","l":"http:\\/\\/www.fotopedia.com\\/items\\/anboto-RiKxAA3gE6I"},"sentences":{"gbs":[{"d":"The Eiffel Tower is one of the most famous monuments in the world (324 metres, 10,100 tonnes).","a":"Paris","l":"http:\\/\\/www.paris.com\\/paris_landmarks\\/monuments\\/eiffel_tower_paris"},{"d":"This is without doubt one of the most recognizable structures in the world.","a":"Frommers","l":"http:\\/\\/www.frommers.com\\/destinations\\/paris\\/A25288.html"},{"d":"If the Statue of Liberty is emblematic of New York, Big Ben is London, and the Kremlin is Moscow, then the Eiffel Tower is the symbol of Paris.","a":"Fodors","l":"http:\\/\\/www.fodors.com\\/world\\/europe\\/france\\/paris\\/review-97417.html"},{"d":"When it was built for the 1889 Exposition Universelle (World Fair), marking the centenary of the Revolution, the Tour Eiffel faced massive opposition from Paris' artistic and literary elite.","a":"Lonely Planet","l":"http:\\/\\/www.lonelyplanet.com\\/france\\/paris\\/sights\\/famous-landmark\\/eiffel-tower"}],"tips":[{"d":"It's pretty high!.","a":"annawelford","l":"http:\\/\\/www.lonelyplanet.com\\/france\\/paris\\/sights\\/famous-landmark\\/eiffel-tower","s":"Lonely Planet"},{"d":"Bigger than you think.","a":"anomolly","l":"http:\\/\\/www.lonelyplanet.com\\/france\\/paris\\/sights\\/famous-landmark\\/eiffel-tower","s":"Lonely Planet"},{"d":"Overcrowded.","a":"anshjain","l":"http:\\/\\/www.lonelyplanet.com\\/france\\/paris\\/sights\\/famous-landmark\\/eiffel-tower","s":"Lonely Planet"},{"d":"The restaurant on the first floor is an amazing experience!.","a":"ansofie","l":"http:\\/\\/www.lonelyplanet.com\\/france\\/paris\\/sights\\/famous-landmark\\/eiffel-tower","s":"Lonely Planet"}]},"tags":["Landmark","Memorials\\/Monuments","Sights","Famous landmark"]}
HGET Pois:PoisHash 52511
samedi 26 octobre 13
![Page 89: Voyager avec play scala](https://reader034.vdocument.in/reader034/viewer/2022051314/555cb69dd8b42ab2358b58b4/html5/thumbnails/89.jpg)
Play 2.1
• Définir une case class POI
• Définir un implicit Json.format[POI]
•C’est tout... ou presque
samedi 26 octobre 13
![Page 90: Voyager avec play scala](https://reader034.vdocument.in/reader034/viewer/2022051314/555cb69dd8b42ab2358b58b4/html5/thumbnails/90.jpg)
Play 2.0
case class POI(name: String, address: String, latitude: String, longitude: String, website: Option[String], photo: Option[SightPhoto] = None, sentences: Sentences, tags: Option[List[String]])
POI = Point of Interest = notre Tour Eiffel
samedi 26 octobre 13
![Page 91: Voyager avec play scala](https://reader034.vdocument.in/reader034/viewer/2022051314/555cb69dd8b42ab2358b58b4/html5/thumbnails/91.jpg)
Play 2.0
samedi 26 octobre 13
![Page 92: Voyager avec play scala](https://reader034.vdocument.in/reader034/viewer/2022051314/555cb69dd8b42ab2358b58b4/html5/thumbnails/92.jpg)
Play 2.1
samedi 26 octobre 13
![Page 93: Voyager avec play scala](https://reader034.vdocument.in/reader034/viewer/2022051314/555cb69dd8b42ab2358b58b4/html5/thumbnails/93.jpg)
Play 2.1(Parser lorsque le JSON stocké sur Redis utilise une déclaration différente
de la case class)
samedi 26 octobre 13
![Page 94: Voyager avec play scala](https://reader034.vdocument.in/reader034/viewer/2022051314/555cb69dd8b42ab2358b58b4/html5/thumbnails/94.jpg)
Appel Redis et interprétation JSON
samedi 26 octobre 13
![Page 95: Voyager avec play scala](https://reader034.vdocument.in/reader034/viewer/2022051314/555cb69dd8b42ab2358b58b4/html5/thumbnails/95.jpg)
Afficher une listeZapTravel
samedi 26 octobre 13
![Page 96: Voyager avec play scala](https://reader034.vdocument.in/reader034/viewer/2022051314/555cb69dd8b42ab2358b58b4/html5/thumbnails/96.jpg)
Afficher une liste
ZapTravel
samedi 26 octobre 13
![Page 97: Voyager avec play scala](https://reader034.vdocument.in/reader034/viewer/2022051314/555cb69dd8b42ab2358b58b4/html5/thumbnails/97.jpg)
Aller sur Redisdef allOrigins: List[Origin] = Redis.pool.withClient { client => // ... // ... }
Modèlesamedi 26 octobre 13
![Page 98: Voyager avec play scala](https://reader034.vdocument.in/reader034/viewer/2022051314/555cb69dd8b42ab2358b58b4/html5/thumbnails/98.jpg)
Préparer une listedef allUrlOrigins: Seq[(String, String)] = { Origin.allOrigins.map{ origin => (origin.slug, origin.label) }.sortBy(_._2)}
Contrôleursamedi 26 octobre 13
![Page 99: Voyager avec play scala](https://reader034.vdocument.in/reader034/viewer/2022051314/555cb69dd8b42ab2358b58b4/html5/thumbnails/99.jpg)
Envoyer la liste au template
<label for="location">Your travel origin is :</label>
@select( userForm("originCity"),
FolioCriteria.allUrlOrigins , '_label -> "Travel from origin", '_showConstraints -> false)
Code dans la page HTML
Vuesamedi 26 octobre 13
![Page 100: Voyager avec play scala](https://reader034.vdocument.in/reader034/viewer/2022051314/555cb69dd8b42ab2358b58b4/html5/thumbnails/100.jpg)
Afficher une liste
ZapTravel
samedi 26 octobre 13
![Page 101: Voyager avec play scala](https://reader034.vdocument.in/reader034/viewer/2022051314/555cb69dd8b42ab2358b58b4/html5/thumbnails/101.jpg)
Gérer l’authentification
samedi 26 octobre 13
![Page 102: Voyager avec play scala](https://reader034.vdocument.in/reader034/viewer/2022051314/555cb69dd8b42ab2358b58b4/html5/thumbnails/102.jpg)
Comment protéger l’accès à une ressource ?
My Info
samedi 26 octobre 13
![Page 103: Voyager avec play scala](https://reader034.vdocument.in/reader034/viewer/2022051314/555cb69dd8b42ab2358b58b4/html5/thumbnails/103.jpg)
Comment protéger l’accès à une ressource ?
My Info
samedi 26 octobre 13
![Page 104: Voyager avec play scala](https://reader034.vdocument.in/reader034/viewer/2022051314/555cb69dd8b42ab2358b58b4/html5/thumbnails/104.jpg)
Dans le Controllerobject Application extends Controller { def index = Action { implicit request => val username="test" Ok(html.index(username)) }
}
samedi 26 octobre 13
![Page 105: Voyager avec play scala](https://reader034.vdocument.in/reader034/viewer/2022051314/555cb69dd8b42ab2358b58b4/html5/thumbnails/105.jpg)
Dans le Controllerobject Application extends Controller with Secured { def index = ActionSecure { username => implicit request => Ok(html.index(username)) }
}
samedi 26 octobre 13
![Page 106: Voyager avec play scala](https://reader034.vdocument.in/reader034/viewer/2022051314/555cb69dd8b42ab2358b58b4/html5/thumbnails/106.jpg)
trait Secured {
def username(request: RequestHeader) = request.session.get(Security.username)
def onUnauthorized(request: RequestHeader) = Results.Redirect(routes.Auth.login)
def ActionSecure(f: => String => Request[AnyContent] => Result) = { Security.Authenticated(username, onUnauthorized) { user => Action{ request => f(user)(request) } } }
} Result
HTMLString Request[AnyContent]
samedi 26 octobre 13
![Page 107: Voyager avec play scala](https://reader034.vdocument.in/reader034/viewer/2022051314/555cb69dd8b42ab2358b58b4/html5/thumbnails/107.jpg)
Play2 et Sécurité
• Simple
•Composable
• Facile à tester
samedi 26 octobre 13
![Page 108: Voyager avec play scala](https://reader034.vdocument.in/reader034/viewer/2022051314/555cb69dd8b42ab2358b58b4/html5/thumbnails/108.jpg)
Optimiser l’indexation et le référencement
samedi 26 octobre 13
![Page 109: Voyager avec play scala](https://reader034.vdocument.in/reader034/viewer/2022051314/555cb69dd8b42ab2358b58b4/html5/thumbnails/109.jpg)
Indexation et référencement
•URLs propres et pondérées
•Mots clés
• Liens et Sitemap
•Microformat (Hotel, Avion, Lieux)
•Contenu non répété
samedi 26 octobre 13
![Page 110: Voyager avec play scala](https://reader034.vdocument.in/reader034/viewer/2022051314/555cb69dd8b42ab2358b58b4/html5/thumbnails/110.jpg)
samedi 26 octobre 13
![Page 111: Voyager avec play scala](https://reader034.vdocument.in/reader034/viewer/2022051314/555cb69dd8b42ab2358b58b4/html5/thumbnails/111.jpg)
routes
Compilé et validé
samedi 26 octobre 13
![Page 112: Voyager avec play scala](https://reader034.vdocument.in/reader034/viewer/2022051314/555cb69dd8b42ab2358b58b4/html5/thumbnails/112.jpg)
URL
GET /$origin<from-(.*)>/:classifier controllers.Frontoffice.home(origin:String, classifier: String)
/from-boston/quality
http://www.zaptravel.com/romance/weekend-deals/from-paris/to-athens/12-Apr-2013-to-14-Apr-2013/elite-athens-greece
samedi 26 octobre 13
![Page 113: Voyager avec play scala](https://reader034.vdocument.in/reader034/viewer/2022051314/555cb69dd8b42ab2358b58b4/html5/thumbnails/113.jpg)
Play2
• La séparation entre la partie routage et la partie contrôleur permet de créer des URLs «propres»
samedi 26 octobre 13
![Page 114: Voyager avec play scala](https://reader034.vdocument.in/reader034/viewer/2022051314/555cb69dd8b42ab2358b58b4/html5/thumbnails/114.jpg)
Sitemap
• Déclarer la table des matières de son site
•Optimise le référencement
• Permet de mettre en cache les pages
curl http://www.zaptravel.com/sitemap.xml
samedi 26 octobre 13
![Page 115: Voyager avec play scala](https://reader034.vdocument.in/reader034/viewer/2022051314/555cb69dd8b42ab2358b58b4/html5/thumbnails/115.jpg)
samedi 26 octobre 13
![Page 116: Voyager avec play scala](https://reader034.vdocument.in/reader034/viewer/2022051314/555cb69dd8b42ab2358b58b4/html5/thumbnails/116.jpg)
Problème : construire le sitemap de façon asynchrone
samedi 26 octobre 13
![Page 117: Voyager avec play scala](https://reader034.vdocument.in/reader034/viewer/2022051314/555cb69dd8b42ab2358b58b4/html5/thumbnails/117.jpg)
Solution : Async
Akka / Play2
samedi 26 octobre 13
![Page 118: Voyager avec play scala](https://reader034.vdocument.in/reader034/viewer/2022051314/555cb69dd8b42ab2358b58b4/html5/thumbnails/118.jpg)
def sitemap = Action { implicit request => val longCall = Akka.future { val today = ZapFormats.formatForJson(new DateTime()) val listOfSEOCards = FolioCard.allForSEO().flatMap { seo => val localURL = routes.Frontoffice.showFolioDynamically(seo.category, seo.duration, seo.origin, seo.destination, seo.dateRange, seo.segment).absoluteURL(secure = false) val updatedUrl = (for (l <- localAddress; p <- publicAddress) yield localURL.replaceAll(l, p)) updatedUrl } Ok(views.xml.Application.sitemap(today, listOfSEOCards)).as("text/xml") } Async { implicit val timeout = akka.util.Timeout(60 seconds) longCall } }
samedi 26 octobre 13
![Page 119: Voyager avec play scala](https://reader034.vdocument.in/reader034/viewer/2022051314/555cb69dd8b42ab2358b58b4/html5/thumbnails/119.jpg)
def sitemap = Action { implicit request => val longCall = Akka.future { val today = ... // some other code val listOfSEOCards = FolioCard.allForSEO().flatMap { seo => val localURL = routes.Frontoffice.showFolioDynamically(seo.category, seo.duration, seo.origin, seo.destination, seo.dateRange, seo.segment).absoluteURL(secure = false) val updatedUrl = (for (l <- localAddress; p <- publicAddress) yield localURL.replaceAll(l, p)) updatedUrl } Ok(views.xml.Application.sitemap(today, listOfSEOCards) ).as("text/xml") } Async { implicit val timeout = akka.util.Timeout(60 seconds) longCall } }
samedi 26 octobre 13
![Page 120: Voyager avec play scala](https://reader034.vdocument.in/reader034/viewer/2022051314/555cb69dd8b42ab2358b58b4/html5/thumbnails/120.jpg)
def sitemap = Action { implicit request => val longCall = Akka.future { val today = ZapFormats.formatForJson(new DateTime()) val listOfSEOCards = FolioCard.allForSEO().flatMap { seo => val localURL = routes.Frontoffice.showFolioDynamically(seo.category, seo.duration, seo.origin, seo.destination, seo.dateRange, seo.segment).absoluteURL(secure = false)
val updatedUrl = (for (l <- localAddress; p <- publicAddress) yield localURL.replaceAll(l, p))
updatedUrl } Ok(views.xml.Application.sitemap(today, listOfSEOCards)).as("text/xml") } Async { implicit val timeout = akka.util.Timeout(60 seconds) longCall } }
samedi 26 octobre 13
![Page 121: Voyager avec play scala](https://reader034.vdocument.in/reader034/viewer/2022051314/555cb69dd8b42ab2358b58b4/html5/thumbnails/121.jpg)
def sitemap = Action { implicit request => val longCall = Akka.future { val today = ZapFormats.formatForJson(new DateTime()) val listOfSEOCards = FolioCard.allForSEO().flatMap { seo => val localURL = routes.Frontoffice.showFolioDynamically(seo.category, seo.duration, seo.origin, seo.destination, seo.dateRange, seo.segment).absoluteURL(secure = false)
val updatedUrl = (for (l <- localAddress; p <- publicAddress) yield localURL.replaceAll(l, p))
updatedUrl } Ok(views.xml.Application.sitemap(today, listOfSEOCards)).as("text/xml") } Async { implicit val timeout = akka.util.Timeout(60 seconds) longCall } }
samedi 26 octobre 13
![Page 122: Voyager avec play scala](https://reader034.vdocument.in/reader034/viewer/2022051314/555cb69dd8b42ab2358b58b4/html5/thumbnails/122.jpg)
def sitemap = Action { implicit request => val longCall = Akka.future { val today = ZapFormats.formatForJson(new DateTime()) val listOfSEOCards = FolioCard.allForSEO().flatMap { seo => val localURL = routes.Frontoffice.showFolioDynamically(seo.category, seo.duration, seo.origin, seo.destination, seo.dateRange, seo.segment).absoluteURL(secure = false)
val updatedUrl = (for (l <- localAddress; p <- publicAddress) yield localURL.replaceAll(l, p))
updatedUrl } Ok(views.xml.Application.sitemap(today, listOfSEOCards)).as("text/xml") } Async { implicit val timeout = akka.util.Timeout(60 seconds) longCall } }
Bref...curl http://www.zaptravel.com/sitemap.xml
samedi 26 octobre 13
![Page 123: Voyager avec play scala](https://reader034.vdocument.in/reader034/viewer/2022051314/555cb69dd8b42ab2358b58b4/html5/thumbnails/123.jpg)
Gestion du cachesamedi 26 octobre 13
![Page 124: Voyager avec play scala](https://reader034.vdocument.in/reader034/viewer/2022051314/555cb69dd8b42ab2358b58b4/html5/thumbnails/124.jpg)
Comment améliorer les performances ?
samedi 26 octobre 13
![Page 125: Voyager avec play scala](https://reader034.vdocument.in/reader034/viewer/2022051314/555cb69dd8b42ab2358b58b4/html5/thumbnails/125.jpg)
Eviter de recharger la même page,
utilisez code 304 NotModified
Note: @rosstuck a fait une session sur HTTP à Confoo mercredi dernier
samedi 26 octobre 13
![Page 126: Voyager avec play scala](https://reader034.vdocument.in/reader034/viewer/2022051314/555cb69dd8b42ab2358b58b4/html5/thumbnails/126.jpg)
Exemple sur /from-paris/quality
Navigateur Play2
GET /from-paris/quality
samedi 26 octobre 13
![Page 127: Voyager avec play scala](https://reader034.vdocument.in/reader034/viewer/2022051314/555cb69dd8b42ab2358b58b4/html5/thumbnails/127.jpg)
Exemple sur /from-paris/qualityNavigateur Play2
OK
HTTP/1.1 200 OKContent-Type: text/html; charset=utf-8ETag: 11299930771Cache-Control: max-age=600, s-maxage=600, must-revalidateContent-Length: 103586......
ce n’est pas une erreur
samedi 26 octobre 13
![Page 128: Voyager avec play scala](https://reader034.vdocument.in/reader034/viewer/2022051314/555cb69dd8b42ab2358b58b4/html5/thumbnails/128.jpg)
Recharge /from-paris/quality
Navigateur Play2
GET /from-paris/qualityIf-None-Match: 112999307771
304 Not ModifiedContent-Length: 0
samedi 26 octobre 13
![Page 129: Voyager avec play scala](https://reader034.vdocument.in/reader034/viewer/2022051314/555cb69dd8b42ab2358b58b4/html5/thumbnails/129.jpg)
Optimisation 1
• Evitez de faire travailler votre serveur pour rien
• Déterminez des ETags «métiers»
• Attention à la gestion du cache et des serveurs mandataires.
samedi 26 octobre 13
![Page 130: Voyager avec play scala](https://reader034.vdocument.in/reader034/viewer/2022051314/555cb69dd8b42ab2358b58b4/html5/thumbnails/130.jpg)
Optimisation 2
Faire de la gestion de cache applicative
samedi 26 octobre 13
![Page 131: Voyager avec play scala](https://reader034.vdocument.in/reader034/viewer/2022051314/555cb69dd8b42ab2358b58b4/html5/thumbnails/131.jpg)
Cache applicatif ?
samedi 26 octobre 13
![Page 132: Voyager avec play scala](https://reader034.vdocument.in/reader034/viewer/2022051314/555cb69dd8b42ab2358b58b4/html5/thumbnails/132.jpg)
2 types de cacheCache technique type Varnish
Cache de Play2 ou Redis
- Process à part- Cache HTTP
- Code applicatif- utilise la mémoire de Play2 ou Redis
samedi 26 octobre 13
![Page 133: Voyager avec play scala](https://reader034.vdocument.in/reader034/viewer/2022051314/555cb69dd8b42ab2358b58b4/html5/thumbnails/133.jpg)
2 types de cache
• Facile à installer
• Evite de solliciter Play2
• Scalable
• Configurable
Cache technique type Varnish
samedi 26 octobre 13
![Page 134: Voyager avec play scala](https://reader034.vdocument.in/reader034/viewer/2022051314/555cb69dd8b42ab2358b58b4/html5/thumbnails/134.jpg)
2 types de cache
• Prend en compte le métier
• Permet de garder les pages «authentifiées»
• Pas aussi performant que la solution Varnish
Cache applicatif Play2/Redis
samedi 26 octobre 13
![Page 135: Voyager avec play scala](https://reader034.vdocument.in/reader034/viewer/2022051314/555cb69dd8b42ab2358b58b4/html5/thumbnails/135.jpg)
Sur Zaptravel• Page d’accueil
optimisé avec Cache de Play2
• Page Folio, section top Deal avec cache Play2
• Page Deal, cache avec Redis
samedi 26 octobre 13
![Page 136: Voyager avec play scala](https://reader034.vdocument.in/reader034/viewer/2022051314/555cb69dd8b42ab2358b58b4/html5/thumbnails/136.jpg)
Et pour terminer
samedi 26 octobre 13
![Page 137: Voyager avec play scala](https://reader034.vdocument.in/reader034/viewer/2022051314/555cb69dd8b42ab2358b58b4/html5/thumbnails/137.jpg)
Merci
@nmartignole
samedi 26 octobre 13