SlideShare uma empresa Scribd logo
1 de 19
Baixar para ler offline
JSON OBJECTS RDBMSTO TO
Stephen Kemmerling
@42eng
CONTACTS AS A SERVICE
Should have JSON endpoints for
• Store contact information
• Retrieval by Name
Contacts as a Service
https://github.com/FortyTwoEng/
Contacts-As-A-Service/blob/master/
app/controllers/Application.scala
• OO Representation
• Handle JSON requests and convert to OO
• Save to DB/Load from DB
What do we need?
• OO Representation
• Handle JSON requests and convert to OO
• Save to DB/Load from DB
What do we need?
SCALA REPRESENTATION
case class Email(addr: String)
case class Contact(
name: String,
phone: Option[Int],
email: Option[Email]
)
• OO Representation
• Handle JSON requests and convert to OO
• Save to DB/Load from DB
What do we need?
SENDING JSON RESPONSES
def lookup(name: String) = Action { request =>
val contacts : Seq[Contact] = loadFromDb(name)
val contactsJson : Seq[JsValue] = contacts.map(Json.toJson(_))
Ok(JsArray(contactsJson))
}
TO/FROM JSON
trait Format[T] {
def reads(json: JsValue): JsResult[T]
def writes(obj: T): JsValue
}
MACROS!
object Contact {
implicit val format: Format[Contact] =
Json.format[Contact]
}
Almost, but not quite: Can’t deal with Email
case class Email(addr: String)
case class Contact(
name: String,
phone: Option[Int],
email: Option[Email]
)
MAGIC!
FORMAT BY HAND
object Email {
implicit format : Format[Email] = Json.format[Email]
}
Let’s not be lazy
FORMAT BY HAND
object Email {
implicit val format = new Format[Email]{
def reads(json: JsValue) : JsResult[Email] = {
json match{
case JsString(s) => JsSuccess(Email(s))
case _ => JsError()
}
}
def writes(email: Email) : JsValue = {
JsString(email.addr)
}
}
}
ACCEPTING JSON
REQUESTS
def store(name: String) = Action(parse.tolerantJson)
{ request =>
val phoneJson : JsValue = request.body  "phone"
val phone : Option[Int] = phoneJson.asOpt[Int]
val email = (request.body  "email").asOpt[Email]
val contact = Contact(name, phone, email)
saveToDb(contact)
Ok(“”)
}
ALL TOGETHER NOW
def lookup(name: String) = Action { request =>
val contacts : Seq[Contact] = loadFromDb(name)
val contactsJson : Seq[JsValue] =
contacts.map(Json.toJson(_))
Ok(JsArray(contactsJson))
}
def store(name: String) = Action(parse.tolerantJson)
{ request =>
val phoneJson : JsValue = request.body  "phone"
val phone : Option[Int] = phoneJson.asOpt[Int]
val email = (request.body  "email").asOpt[Email]
val contact = Contact(name, phone, email)
saveToDb(contact)
Ok(“”)
}
• OO Representation
• Handle JSON requests and convert to OO
• Save to DB/Load from DB
What do we need?
SLICK TABLE DEFINITION
object Contacts extends Table[Contact]("contacts") {
def name = column[String]("name", O.PrimaryKey)
def phone = column[Int]("phone", O.Nullable)
def email = column[Email]("email", O.Nullable)
def * = name ~ phone.? ~ email.?
<> (Contact.apply _, Contact.unapply _)
}
INSERTS AND LOOKUPS
def saveToDb(contact: Contact) =
database.withSession{ implicit session: Session =>
Contacts.*.insert(contact)
}
def loadFromDb(name: String) =
database.withSession{ implicit session: Session =>
(for (row <- Contacts if row.name===name) yield row).list
}
SLICK TABLE DEFINITION
object Contacts extends Table[Contact]("contacts") {
def name = column[String]("name", O.PrimaryKey)
def phone = column[Int]("phone", O.Nullable)
def email = column[Email]("email", O.Nullable)
def * = name ~ phone.? ~ email.?
<> (Contact.apply _, Contact.unapply _)
}
def saveToDb(contact: Contact) =
database.withSession{ implicit session: Session =>
Contacts.*.insert(contact)
}
def loadFromDb(name: String) =
database.withSession{ implicit session: Session =>
(for (row <- Contacts if row.name===name) yield row).list
}
TYPE MAPPER
implicit object typeMapper extends BaseTypeMapper[Email] {
def apply(profile: BasicProfile) : TypeMapperDelegate[Email] = {
val delegate = profile.typeMapperDelegates.stringTypeMapperDelegate
new TypeMapperDelegate[Email] {
def sqlType = delegate.sqlType
def setValue(value: Email, p: PositionedParameters) =
delegate.setValue(value.addr, p)
def setOption(valueOpt: Option[Email], p: PositionedParameters) =
delegate.setOption(valueOpt.map(_.addr), p)
def nextValue(r: PositionedResult): Email =
Email(delegate.nextValue(r))
def sqlTypeName = delegate.sqlTypeName
def updateValue(value: Email, r: PositionedResult) =
delegate.updateValue(value.addr, r)
def zero = Email("towel@42go.com")
}
}
}
e class Email(addr: String)
ect Email {mplicit val format = new
mat[Email]{def reads(json: JsValue) :
sult[Email] = {
json match{case JsString(s) =>
cess(Email(s))case _ => JsError()
}
f writes(email: Email) :
e = {sString(email.addr)
p(name: String) =
rse.json) { request =>
acts : Seq[Contact] =
(name)actsJson : Seq[J
ts.map(J
object Contacts extends
Table[Contact]("contacts") {
def name = column[String]
("name", O.PrimaryKey)
def phone = column[Int]
("phone", O.Nullable)
def email = column[Email]
("email", O.Nullable)
def * = name ~ phone.? ~
email.?
<> (Contact.apply _,
Contact.unapply _)
}
def saveToDb(contact:
database.with
session
meters) =
[Email], p:
gate.setOption(valueOpt.map(_.addr),
Value(r: PositionedResult): Email =
delegate.nextValue(r))
def sqlTypeName = delegate.sqlTypeName
def updateValue(value: Email, r: PositionedResult) =
delegate.updateValue(value.addr, r)
def zero = Email("towel@42go.com")
}
}
}
case class Contact(
name: String,
phone: Option[Int],
email: Option[Email]
)
object Contact {
implicit format : Format[Contact] =
}
SOURCE: https://github.com/FortyTwoEng/Contacts-As-A-Service
FOLLOW US: @42ENG
JOIN US: 42GO.COM/JOIN_US.HTML

Mais conteúdo relacionado

Mais procurados

The Ring programming language version 1.8 book - Part 43 of 202
The Ring programming language version 1.8 book - Part 43 of 202The Ring programming language version 1.8 book - Part 43 of 202
The Ring programming language version 1.8 book - Part 43 of 202Mahmoud Samir Fayed
 
The Ring programming language version 1.3 book - Part 33 of 88
The Ring programming language version 1.3 book - Part 33 of 88The Ring programming language version 1.3 book - Part 33 of 88
The Ring programming language version 1.3 book - Part 33 of 88Mahmoud Samir Fayed
 
The Ring programming language version 1.5.2 book - Part 35 of 181
The Ring programming language version 1.5.2 book - Part 35 of 181The Ring programming language version 1.5.2 book - Part 35 of 181
The Ring programming language version 1.5.2 book - Part 35 of 181Mahmoud Samir Fayed
 
Jython: Python para la plataforma Java (EL2009)
Jython: Python para la plataforma Java (EL2009)Jython: Python para la plataforma Java (EL2009)
Jython: Python para la plataforma Java (EL2009)Leonardo Soto
 
The Ring programming language version 1.5.3 book - Part 30 of 184
The Ring programming language version 1.5.3 book - Part 30 of 184The Ring programming language version 1.5.3 book - Part 30 of 184
The Ring programming language version 1.5.3 book - Part 30 of 184Mahmoud Samir Fayed
 
Jython: Python para la plataforma Java (JRSL 09)
Jython: Python para la plataforma Java (JRSL 09)Jython: Python para la plataforma Java (JRSL 09)
Jython: Python para la plataforma Java (JRSL 09)Leonardo Soto
 
The Ring programming language version 1.3 book - Part 14 of 88
The Ring programming language version 1.3 book - Part 14 of 88The Ring programming language version 1.3 book - Part 14 of 88
The Ring programming language version 1.3 book - Part 14 of 88Mahmoud Samir Fayed
 
Refactoring to Macros with Clojure
Refactoring to Macros with ClojureRefactoring to Macros with Clojure
Refactoring to Macros with ClojureDmitry Buzdin
 
The Ring programming language version 1.2 book - Part 19 of 84
The Ring programming language version 1.2 book - Part 19 of 84The Ring programming language version 1.2 book - Part 19 of 84
The Ring programming language version 1.2 book - Part 19 of 84Mahmoud Samir Fayed
 
Using spark data frame for sql
Using spark data frame for sqlUsing spark data frame for sql
Using spark data frame for sqlDaeMyung Kang
 
From java to kotlin beyond alt+shift+cmd+k - Droidcon italy
From java to kotlin beyond alt+shift+cmd+k - Droidcon italyFrom java to kotlin beyond alt+shift+cmd+k - Droidcon italy
From java to kotlin beyond alt+shift+cmd+k - Droidcon italyFabio Collini
 
Poor Man's Functional Programming
Poor Man's Functional ProgrammingPoor Man's Functional Programming
Poor Man's Functional ProgrammingDmitry Buzdin
 
The Ring programming language version 1.7 book - Part 48 of 196
The Ring programming language version 1.7 book - Part 48 of 196The Ring programming language version 1.7 book - Part 48 of 196
The Ring programming language version 1.7 book - Part 48 of 196Mahmoud Samir Fayed
 
Ciklum net sat12112011-alexander fomin-expressions and all, all, all
Ciklum net sat12112011-alexander fomin-expressions and all, all, allCiklum net sat12112011-alexander fomin-expressions and all, all, all
Ciklum net sat12112011-alexander fomin-expressions and all, all, allCiklum Ukraine
 

Mais procurados (19)

PureScript & Pux
PureScript & PuxPureScript & Pux
PureScript & Pux
 
The Ring programming language version 1.8 book - Part 43 of 202
The Ring programming language version 1.8 book - Part 43 of 202The Ring programming language version 1.8 book - Part 43 of 202
The Ring programming language version 1.8 book - Part 43 of 202
 
The Ring programming language version 1.3 book - Part 33 of 88
The Ring programming language version 1.3 book - Part 33 of 88The Ring programming language version 1.3 book - Part 33 of 88
The Ring programming language version 1.3 book - Part 33 of 88
 
The Ring programming language version 1.5.2 book - Part 35 of 181
The Ring programming language version 1.5.2 book - Part 35 of 181The Ring programming language version 1.5.2 book - Part 35 of 181
The Ring programming language version 1.5.2 book - Part 35 of 181
 
Jython: Python para la plataforma Java (EL2009)
Jython: Python para la plataforma Java (EL2009)Jython: Python para la plataforma Java (EL2009)
Jython: Python para la plataforma Java (EL2009)
 
The Ring programming language version 1.5.3 book - Part 30 of 184
The Ring programming language version 1.5.3 book - Part 30 of 184The Ring programming language version 1.5.3 book - Part 30 of 184
The Ring programming language version 1.5.3 book - Part 30 of 184
 
Enter The Matrix
Enter The MatrixEnter The Matrix
Enter The Matrix
 
Jython: Python para la plataforma Java (JRSL 09)
Jython: Python para la plataforma Java (JRSL 09)Jython: Python para la plataforma Java (JRSL 09)
Jython: Python para la plataforma Java (JRSL 09)
 
The Ring programming language version 1.3 book - Part 14 of 88
The Ring programming language version 1.3 book - Part 14 of 88The Ring programming language version 1.3 book - Part 14 of 88
The Ring programming language version 1.3 book - Part 14 of 88
 
R environment
R environmentR environment
R environment
 
Sparklyr
SparklyrSparklyr
Sparklyr
 
Refactoring to Macros with Clojure
Refactoring to Macros with ClojureRefactoring to Macros with Clojure
Refactoring to Macros with Clojure
 
The Ring programming language version 1.2 book - Part 19 of 84
The Ring programming language version 1.2 book - Part 19 of 84The Ring programming language version 1.2 book - Part 19 of 84
The Ring programming language version 1.2 book - Part 19 of 84
 
Using spark data frame for sql
Using spark data frame for sqlUsing spark data frame for sql
Using spark data frame for sql
 
From java to kotlin beyond alt+shift+cmd+k - Droidcon italy
From java to kotlin beyond alt+shift+cmd+k - Droidcon italyFrom java to kotlin beyond alt+shift+cmd+k - Droidcon italy
From java to kotlin beyond alt+shift+cmd+k - Droidcon italy
 
Poor Man's Functional Programming
Poor Man's Functional ProgrammingPoor Man's Functional Programming
Poor Man's Functional Programming
 
Scala on Your Phone
Scala on Your PhoneScala on Your Phone
Scala on Your Phone
 
The Ring programming language version 1.7 book - Part 48 of 196
The Ring programming language version 1.7 book - Part 48 of 196The Ring programming language version 1.7 book - Part 48 of 196
The Ring programming language version 1.7 book - Part 48 of 196
 
Ciklum net sat12112011-alexander fomin-expressions and all, all, all
Ciklum net sat12112011-alexander fomin-expressions and all, all, allCiklum net sat12112011-alexander fomin-expressions and all, all, all
Ciklum net sat12112011-alexander fomin-expressions and all, all, all
 

Semelhante a Json and SQL DB serialization Introduction with Play! and Slick

Http4s, Doobie and Circe: The Functional Web Stack
Http4s, Doobie and Circe: The Functional Web StackHttp4s, Doobie and Circe: The Functional Web Stack
Http4s, Doobie and Circe: The Functional Web StackGaryCoady
 
Power of functions in a typed world
Power of functions in a typed worldPower of functions in a typed world
Power of functions in a typed worldDebasish Ghosh
 
JSON Data Parsing in Snowflake (By Faysal Shaarani)
JSON Data Parsing in Snowflake (By Faysal Shaarani)JSON Data Parsing in Snowflake (By Faysal Shaarani)
JSON Data Parsing in Snowflake (By Faysal Shaarani)Faysal Shaarani (MBA)
 
Creating Domain Specific Languages in Python
Creating Domain Specific Languages in PythonCreating Domain Specific Languages in Python
Creating Domain Specific Languages in PythonSiddhi
 
Oracle Database - JSON and the In-Memory Database
Oracle Database - JSON and the In-Memory DatabaseOracle Database - JSON and the In-Memory Database
Oracle Database - JSON and the In-Memory DatabaseMarco Gralike
 
Graph Database Query Languages
Graph Database Query LanguagesGraph Database Query Languages
Graph Database Query LanguagesJay Coskey
 
TDC2018SP | Trilha Java - Java SE 8 for Java EE Developers
TDC2018SP | Trilha Java - Java SE 8 for Java EE DevelopersTDC2018SP | Trilha Java - Java SE 8 for Java EE Developers
TDC2018SP | Trilha Java - Java SE 8 for Java EE Developerstdc-globalcode
 
Ext GWT 3.0 Data Widgets
Ext GWT 3.0 Data WidgetsExt GWT 3.0 Data Widgets
Ext GWT 3.0 Data WidgetsSencha
 
The Death of Final Tagless
The Death of Final TaglessThe Death of Final Tagless
The Death of Final TaglessJohn De Goes
 
From Java to Parellel Clojure - Clojure South 2019
From Java to Parellel Clojure - Clojure South 2019From Java to Parellel Clojure - Clojure South 2019
From Java to Parellel Clojure - Clojure South 2019Leonardo Borges
 
Basics of Python programming (part 2)
Basics of Python programming (part 2)Basics of Python programming (part 2)
Basics of Python programming (part 2)Pedro Rodrigues
 
Introduction To NHibernate
Introduction To NHibernateIntroduction To NHibernate
Introduction To NHibernateEmad Alashi
 
ZIO Prelude - ZIO World 2021
ZIO Prelude - ZIO World 2021ZIO Prelude - ZIO World 2021
ZIO Prelude - ZIO World 2021Jorge Vásquez
 

Semelhante a Json and SQL DB serialization Introduction with Play! and Slick (20)

Http4s, Doobie and Circe: The Functional Web Stack
Http4s, Doobie and Circe: The Functional Web StackHttp4s, Doobie and Circe: The Functional Web Stack
Http4s, Doobie and Circe: The Functional Web Stack
 
Sql Server 2000
Sql Server 2000Sql Server 2000
Sql Server 2000
 
Scala best practices
Scala best practicesScala best practices
Scala best practices
 
Power of functions in a typed world
Power of functions in a typed worldPower of functions in a typed world
Power of functions in a typed world
 
JSON Data Parsing in Snowflake (By Faysal Shaarani)
JSON Data Parsing in Snowflake (By Faysal Shaarani)JSON Data Parsing in Snowflake (By Faysal Shaarani)
JSON Data Parsing in Snowflake (By Faysal Shaarani)
 
Creating Domain Specific Languages in Python
Creating Domain Specific Languages in PythonCreating Domain Specific Languages in Python
Creating Domain Specific Languages in Python
 
Oracle Database - JSON and the In-Memory Database
Oracle Database - JSON and the In-Memory DatabaseOracle Database - JSON and the In-Memory Database
Oracle Database - JSON and the In-Memory Database
 
Graph Database Query Languages
Graph Database Query LanguagesGraph Database Query Languages
Graph Database Query Languages
 
Python crush course
Python crush coursePython crush course
Python crush course
 
Relational+algebra (1)
Relational+algebra (1)Relational+algebra (1)
Relational+algebra (1)
 
TDC2018SP | Trilha Java - Java SE 8 for Java EE Developers
TDC2018SP | Trilha Java - Java SE 8 for Java EE DevelopersTDC2018SP | Trilha Java - Java SE 8 for Java EE Developers
TDC2018SP | Trilha Java - Java SE 8 for Java EE Developers
 
Ext GWT 3.0 Data Widgets
Ext GWT 3.0 Data WidgetsExt GWT 3.0 Data Widgets
Ext GWT 3.0 Data Widgets
 
The Death of Final Tagless
The Death of Final TaglessThe Death of Final Tagless
The Death of Final Tagless
 
From Java to Parellel Clojure - Clojure South 2019
From Java to Parellel Clojure - Clojure South 2019From Java to Parellel Clojure - Clojure South 2019
From Java to Parellel Clojure - Clojure South 2019
 
Basics of Python programming (part 2)
Basics of Python programming (part 2)Basics of Python programming (part 2)
Basics of Python programming (part 2)
 
Json
JsonJson
Json
 
Introduction To NHibernate
Introduction To NHibernateIntroduction To NHibernate
Introduction To NHibernate
 
ZIO Prelude - ZIO World 2021
ZIO Prelude - ZIO World 2021ZIO Prelude - ZIO World 2021
ZIO Prelude - ZIO World 2021
 
Json
JsonJson
Json
 
CSV JSON and XML files in Python.pptx
CSV JSON and XML files in Python.pptxCSV JSON and XML files in Python.pptx
CSV JSON and XML files in Python.pptx
 

Último

Gen AI in Business - Global Trends Report 2024.pdf
Gen AI in Business - Global Trends Report 2024.pdfGen AI in Business - Global Trends Report 2024.pdf
Gen AI in Business - Global Trends Report 2024.pdfAddepto
 
Use of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptx
Use of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptxUse of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptx
Use of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptxLoriGlavin3
 
Time Series Foundation Models - current state and future directions
Time Series Foundation Models - current state and future directionsTime Series Foundation Models - current state and future directions
Time Series Foundation Models - current state and future directionsNathaniel Shimoni
 
The Ultimate Guide to Choosing WordPress Pros and Cons
The Ultimate Guide to Choosing WordPress Pros and ConsThe Ultimate Guide to Choosing WordPress Pros and Cons
The Ultimate Guide to Choosing WordPress Pros and ConsPixlogix Infotech
 
"Debugging python applications inside k8s environment", Andrii Soldatenko
"Debugging python applications inside k8s environment", Andrii Soldatenko"Debugging python applications inside k8s environment", Andrii Soldatenko
"Debugging python applications inside k8s environment", Andrii SoldatenkoFwdays
 
Dev Dives: Streamline document processing with UiPath Studio Web
Dev Dives: Streamline document processing with UiPath Studio WebDev Dives: Streamline document processing with UiPath Studio Web
Dev Dives: Streamline document processing with UiPath Studio WebUiPathCommunity
 
A Journey Into the Emotions of Software Developers
A Journey Into the Emotions of Software DevelopersA Journey Into the Emotions of Software Developers
A Journey Into the Emotions of Software DevelopersNicole Novielli
 
The Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptx
The Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptxThe Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptx
The Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptxLoriGlavin3
 
Rise of the Machines: Known As Drones...
Rise of the Machines: Known As Drones...Rise of the Machines: Known As Drones...
Rise of the Machines: Known As Drones...Rick Flair
 
The Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptx
The Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptxThe Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptx
The Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptxLoriGlavin3
 
"ML in Production",Oleksandr Bagan
"ML in Production",Oleksandr Bagan"ML in Production",Oleksandr Bagan
"ML in Production",Oleksandr BaganFwdays
 
A Deep Dive on Passkeys: FIDO Paris Seminar.pptx
A Deep Dive on Passkeys: FIDO Paris Seminar.pptxA Deep Dive on Passkeys: FIDO Paris Seminar.pptx
A Deep Dive on Passkeys: FIDO Paris Seminar.pptxLoriGlavin3
 
From Family Reminiscence to Scholarly Archive .
From Family Reminiscence to Scholarly Archive .From Family Reminiscence to Scholarly Archive .
From Family Reminiscence to Scholarly Archive .Alan Dix
 
The State of Passkeys with FIDO Alliance.pptx
The State of Passkeys with FIDO Alliance.pptxThe State of Passkeys with FIDO Alliance.pptx
The State of Passkeys with FIDO Alliance.pptxLoriGlavin3
 
Moving Beyond Passwords: FIDO Paris Seminar.pdf
Moving Beyond Passwords: FIDO Paris Seminar.pdfMoving Beyond Passwords: FIDO Paris Seminar.pdf
Moving Beyond Passwords: FIDO Paris Seminar.pdfLoriGlavin3
 
Training state-of-the-art general text embedding
Training state-of-the-art general text embeddingTraining state-of-the-art general text embedding
Training state-of-the-art general text embeddingZilliz
 
SIP trunking in Janus @ Kamailio World 2024
SIP trunking in Janus @ Kamailio World 2024SIP trunking in Janus @ Kamailio World 2024
SIP trunking in Janus @ Kamailio World 2024Lorenzo Miniero
 
TrustArc Webinar - How to Build Consumer Trust Through Data Privacy
TrustArc Webinar - How to Build Consumer Trust Through Data PrivacyTrustArc Webinar - How to Build Consumer Trust Through Data Privacy
TrustArc Webinar - How to Build Consumer Trust Through Data PrivacyTrustArc
 
WordPress Websites for Engineers: Elevate Your Brand
WordPress Websites for Engineers: Elevate Your BrandWordPress Websites for Engineers: Elevate Your Brand
WordPress Websites for Engineers: Elevate Your Brandgvaughan
 
What's New in Teams Calling, Meetings and Devices March 2024
What's New in Teams Calling, Meetings and Devices March 2024What's New in Teams Calling, Meetings and Devices March 2024
What's New in Teams Calling, Meetings and Devices March 2024Stephanie Beckett
 

Último (20)

Gen AI in Business - Global Trends Report 2024.pdf
Gen AI in Business - Global Trends Report 2024.pdfGen AI in Business - Global Trends Report 2024.pdf
Gen AI in Business - Global Trends Report 2024.pdf
 
Use of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptx
Use of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptxUse of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptx
Use of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptx
 
Time Series Foundation Models - current state and future directions
Time Series Foundation Models - current state and future directionsTime Series Foundation Models - current state and future directions
Time Series Foundation Models - current state and future directions
 
The Ultimate Guide to Choosing WordPress Pros and Cons
The Ultimate Guide to Choosing WordPress Pros and ConsThe Ultimate Guide to Choosing WordPress Pros and Cons
The Ultimate Guide to Choosing WordPress Pros and Cons
 
"Debugging python applications inside k8s environment", Andrii Soldatenko
"Debugging python applications inside k8s environment", Andrii Soldatenko"Debugging python applications inside k8s environment", Andrii Soldatenko
"Debugging python applications inside k8s environment", Andrii Soldatenko
 
Dev Dives: Streamline document processing with UiPath Studio Web
Dev Dives: Streamline document processing with UiPath Studio WebDev Dives: Streamline document processing with UiPath Studio Web
Dev Dives: Streamline document processing with UiPath Studio Web
 
A Journey Into the Emotions of Software Developers
A Journey Into the Emotions of Software DevelopersA Journey Into the Emotions of Software Developers
A Journey Into the Emotions of Software Developers
 
The Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptx
The Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptxThe Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptx
The Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptx
 
Rise of the Machines: Known As Drones...
Rise of the Machines: Known As Drones...Rise of the Machines: Known As Drones...
Rise of the Machines: Known As Drones...
 
The Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptx
The Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptxThe Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptx
The Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptx
 
"ML in Production",Oleksandr Bagan
"ML in Production",Oleksandr Bagan"ML in Production",Oleksandr Bagan
"ML in Production",Oleksandr Bagan
 
A Deep Dive on Passkeys: FIDO Paris Seminar.pptx
A Deep Dive on Passkeys: FIDO Paris Seminar.pptxA Deep Dive on Passkeys: FIDO Paris Seminar.pptx
A Deep Dive on Passkeys: FIDO Paris Seminar.pptx
 
From Family Reminiscence to Scholarly Archive .
From Family Reminiscence to Scholarly Archive .From Family Reminiscence to Scholarly Archive .
From Family Reminiscence to Scholarly Archive .
 
The State of Passkeys with FIDO Alliance.pptx
The State of Passkeys with FIDO Alliance.pptxThe State of Passkeys with FIDO Alliance.pptx
The State of Passkeys with FIDO Alliance.pptx
 
Moving Beyond Passwords: FIDO Paris Seminar.pdf
Moving Beyond Passwords: FIDO Paris Seminar.pdfMoving Beyond Passwords: FIDO Paris Seminar.pdf
Moving Beyond Passwords: FIDO Paris Seminar.pdf
 
Training state-of-the-art general text embedding
Training state-of-the-art general text embeddingTraining state-of-the-art general text embedding
Training state-of-the-art general text embedding
 
SIP trunking in Janus @ Kamailio World 2024
SIP trunking in Janus @ Kamailio World 2024SIP trunking in Janus @ Kamailio World 2024
SIP trunking in Janus @ Kamailio World 2024
 
TrustArc Webinar - How to Build Consumer Trust Through Data Privacy
TrustArc Webinar - How to Build Consumer Trust Through Data PrivacyTrustArc Webinar - How to Build Consumer Trust Through Data Privacy
TrustArc Webinar - How to Build Consumer Trust Through Data Privacy
 
WordPress Websites for Engineers: Elevate Your Brand
WordPress Websites for Engineers: Elevate Your BrandWordPress Websites for Engineers: Elevate Your Brand
WordPress Websites for Engineers: Elevate Your Brand
 
What's New in Teams Calling, Meetings and Devices March 2024
What's New in Teams Calling, Meetings and Devices March 2024What's New in Teams Calling, Meetings and Devices March 2024
What's New in Teams Calling, Meetings and Devices March 2024
 

Json and SQL DB serialization Introduction with Play! and Slick

  • 1. JSON OBJECTS RDBMSTO TO Stephen Kemmerling @42eng
  • 2. CONTACTS AS A SERVICE Should have JSON endpoints for • Store contact information • Retrieval by Name Contacts as a Service https://github.com/FortyTwoEng/ Contacts-As-A-Service/blob/master/ app/controllers/Application.scala
  • 3. • OO Representation • Handle JSON requests and convert to OO • Save to DB/Load from DB What do we need?
  • 4. • OO Representation • Handle JSON requests and convert to OO • Save to DB/Load from DB What do we need?
  • 5. SCALA REPRESENTATION case class Email(addr: String) case class Contact( name: String, phone: Option[Int], email: Option[Email] )
  • 6. • OO Representation • Handle JSON requests and convert to OO • Save to DB/Load from DB What do we need?
  • 7. SENDING JSON RESPONSES def lookup(name: String) = Action { request => val contacts : Seq[Contact] = loadFromDb(name) val contactsJson : Seq[JsValue] = contacts.map(Json.toJson(_)) Ok(JsArray(contactsJson)) }
  • 8. TO/FROM JSON trait Format[T] { def reads(json: JsValue): JsResult[T] def writes(obj: T): JsValue }
  • 9. MACROS! object Contact { implicit val format: Format[Contact] = Json.format[Contact] } Almost, but not quite: Can’t deal with Email case class Email(addr: String) case class Contact( name: String, phone: Option[Int], email: Option[Email] ) MAGIC!
  • 10. FORMAT BY HAND object Email { implicit format : Format[Email] = Json.format[Email] } Let’s not be lazy
  • 11. FORMAT BY HAND object Email { implicit val format = new Format[Email]{ def reads(json: JsValue) : JsResult[Email] = { json match{ case JsString(s) => JsSuccess(Email(s)) case _ => JsError() } } def writes(email: Email) : JsValue = { JsString(email.addr) } } }
  • 12. ACCEPTING JSON REQUESTS def store(name: String) = Action(parse.tolerantJson) { request => val phoneJson : JsValue = request.body "phone" val phone : Option[Int] = phoneJson.asOpt[Int] val email = (request.body "email").asOpt[Email] val contact = Contact(name, phone, email) saveToDb(contact) Ok(“”) }
  • 13. ALL TOGETHER NOW def lookup(name: String) = Action { request => val contacts : Seq[Contact] = loadFromDb(name) val contactsJson : Seq[JsValue] = contacts.map(Json.toJson(_)) Ok(JsArray(contactsJson)) } def store(name: String) = Action(parse.tolerantJson) { request => val phoneJson : JsValue = request.body "phone" val phone : Option[Int] = phoneJson.asOpt[Int] val email = (request.body "email").asOpt[Email] val contact = Contact(name, phone, email) saveToDb(contact) Ok(“”) }
  • 14. • OO Representation • Handle JSON requests and convert to OO • Save to DB/Load from DB What do we need?
  • 15. SLICK TABLE DEFINITION object Contacts extends Table[Contact]("contacts") { def name = column[String]("name", O.PrimaryKey) def phone = column[Int]("phone", O.Nullable) def email = column[Email]("email", O.Nullable) def * = name ~ phone.? ~ email.? <> (Contact.apply _, Contact.unapply _) }
  • 16. INSERTS AND LOOKUPS def saveToDb(contact: Contact) = database.withSession{ implicit session: Session => Contacts.*.insert(contact) } def loadFromDb(name: String) = database.withSession{ implicit session: Session => (for (row <- Contacts if row.name===name) yield row).list }
  • 17. SLICK TABLE DEFINITION object Contacts extends Table[Contact]("contacts") { def name = column[String]("name", O.PrimaryKey) def phone = column[Int]("phone", O.Nullable) def email = column[Email]("email", O.Nullable) def * = name ~ phone.? ~ email.? <> (Contact.apply _, Contact.unapply _) } def saveToDb(contact: Contact) = database.withSession{ implicit session: Session => Contacts.*.insert(contact) } def loadFromDb(name: String) = database.withSession{ implicit session: Session => (for (row <- Contacts if row.name===name) yield row).list }
  • 18. TYPE MAPPER implicit object typeMapper extends BaseTypeMapper[Email] { def apply(profile: BasicProfile) : TypeMapperDelegate[Email] = { val delegate = profile.typeMapperDelegates.stringTypeMapperDelegate new TypeMapperDelegate[Email] { def sqlType = delegate.sqlType def setValue(value: Email, p: PositionedParameters) = delegate.setValue(value.addr, p) def setOption(valueOpt: Option[Email], p: PositionedParameters) = delegate.setOption(valueOpt.map(_.addr), p) def nextValue(r: PositionedResult): Email = Email(delegate.nextValue(r)) def sqlTypeName = delegate.sqlTypeName def updateValue(value: Email, r: PositionedResult) = delegate.updateValue(value.addr, r) def zero = Email("towel@42go.com") } } }
  • 19. e class Email(addr: String) ect Email {mplicit val format = new mat[Email]{def reads(json: JsValue) : sult[Email] = { json match{case JsString(s) => cess(Email(s))case _ => JsError() } f writes(email: Email) : e = {sString(email.addr) p(name: String) = rse.json) { request => acts : Seq[Contact] = (name)actsJson : Seq[J ts.map(J object Contacts extends Table[Contact]("contacts") { def name = column[String] ("name", O.PrimaryKey) def phone = column[Int] ("phone", O.Nullable) def email = column[Email] ("email", O.Nullable) def * = name ~ phone.? ~ email.? <> (Contact.apply _, Contact.unapply _) } def saveToDb(contact: database.with session meters) = [Email], p: gate.setOption(valueOpt.map(_.addr), Value(r: PositionedResult): Email = delegate.nextValue(r)) def sqlTypeName = delegate.sqlTypeName def updateValue(value: Email, r: PositionedResult) = delegate.updateValue(value.addr, r) def zero = Email("towel@42go.com") } } } case class Contact( name: String, phone: Option[Int], email: Option[Email] ) object Contact { implicit format : Format[Contact] = } SOURCE: https://github.com/FortyTwoEng/Contacts-As-A-Service FOLLOW US: @42ENG JOIN US: 42GO.COM/JOIN_US.HTML