SlideShare a Scribd company logo
Codable

The key to Fullstack Swift
Swift Cloud Workshop 3

February 23rd, 2018
Chris Bailey

(@Chris__Bailey)
Codable
struct Profile {
var name: String
var photo: Data
var dateOfBirth: Date
}
let profile = Profile(name: “Chris”, photo: image, dateOfBirth: Date(“06-06-1980”))
struct Profile : Codable {
var name: String
var photo: Data
var dateOfBirth: Date
}
let profile = Profile(name: “Chris”, photo: image, dateOfBirth: Date(“06-06-1980”))
struct Profile : Codable {
var name: String
var photo: Data
var dateOfBirth: Date
}
let profile = Profile(name: “Chris”, photo: image, dateOfBirth: Date(“06-06-1980”))
let encoder = JSONEncoder()
let jsonData = try encoder.encode(profile)
struct Profile : Codable {
var name: String
var photo: Data
var dateOfBirth: Date
}
let profile = Profile(name: “Chris”, photo: image, dateOfBirth: Date(“06-06-1980”))
let encoder = JSONEncoder()
let jsonData = try encoder.encode(profile)
let decoder = JSONDecoder()
let person = try decoder.decode(Profile.self, from: jsonData)
Fullstack

Development
{
"name": "",
"photo": "",
"dateOfBirth": ""
}
{
"name": "",
"photo": "",
"dateOfBirth": {
"year":
"month":
"day":
}
}
struct Profile {
var name: String
var photo: Data
var dateOfBirth: Date
}
Swift
var profile: [String : Any]
Swift
KITURA
let profile = Profile(name: name, photo: photo)let json = JSON(data: data)

guard json["name"].exists() else {
response.status(.unprocessableEntity)
response.send(json: JSON([ "error": "Missing reqired property `name`" ]))
next()
}
guard let photo = Data(base64Encoded: photoString) else {
response.status(.unprocessableEntity)
response.send(json: JSON([ "error": "Type mismatch, `photo` expected to be Base64 encoded data" ]))
next()
}
guard let name = json["name"].string else {
response.status(.unprocessableEntity)
response.send(json: JSON([ "error": "Type mismatch, `name` expected to be a String" ]))
next()
}
guard json["photo"].exists() else {
response.status(.unprocessableEntity)
response.send(json: JSON([ "error": "Missing reqired property photo`" ]))
next()
}
guard let photoString = json[“photo"].string else {
response.status(.unprocessableEntity)
response.send(json: JSON([ "error": "Type mismatch, `photo` expected to be a String" ]))
next()
}
Swift Cloud Workshop - Codable, the key to Fullstack Swift
Swift Cloud Workshop - Codable, the key to Fullstack Swift
Swift Cloud Workshop - Codable, the key to Fullstack Swift
Swift Cloud Workshop - Codable, the key to Fullstack Swift
Swift Cloud Workshop - Codable, the key to Fullstack Swift
Swift Cloud Workshop - Codable, the key to Fullstack Swift
struct Profile {
var name: String
var photo: Data
var dateOfBirth: Date
}
Swift
struct Profile {
var name: String
var photo: Data
var dateOfBirth: Date
}
Swift Swift
KITURA
struct Profile: Codable {
var name: String
var photo: Data
var dateOfBirth: Date
}
Swift Swift
KITURA
struct Profile: Codable {
var name: String
var photo: Data
var dateOfBirth: Date
}
Swift Swift
struct Profile: Codable {
var name: String
var photo: Data
var dateOfBirth: Date
}
KITURA
struct Profile: Codable {
var name: String
var photo: Data
var dateOfBirth: Date
}
Swift Swift
struct Profile: Codable {
var name: String
var photo: Data
var dateOfBirth: Date
}
let encoder = JSONEncoder()
let data = try encoder.encode(profile)
KITURA
struct Profile: Codable {
var name: String
var photo: Data
var dateOfBirth: Date
}
Swift Swift
struct Profile: Codable {
var name: String
var photo: Data
var dateOfBirth: Date
}
let decoder = JSONDecoder()
let person = try decoder.decode(Person.self, from: jsonData)
KITURA
{
"name": "",
"photo": "",
"dateOfBirth": ""
}
{
"name": "",
"photo": "",
"dateOfBirth": ""
}
struct Profile: Codable {
var name: String
var photo: Data
var dateOfBirth: Date
}
Swift Swift
struct Profile: Codable {
var name: String
var photo: Data
var dateOfBirth: Date
}
KITURA
struct Profile: Codable {
var name: String
var photo: Data
var dateOfBirth: Date
}
Swift Swift
struct Profile: Codable {
var name: String
var photo: Data
var dateOfBirth: Date
}
KITURA
struct Profile: Codable {
var name: String
var photo: Data
var dateOfBirth: Date
}
Swift Swift
struct Profile: Codable {
var name: String
var photo: Data
var dateOfBirth: Date
}
KITURA
struct Profile: Codable {
var name: String
var photo: Data
var dateOfBirth: Date
}
Swift Swift
struct Profile: Codable {
var name: String
var photo: Data
var dateOfBirth: Date
}
KITURA
Under the Hood
struct Profile {
var name: String
var photo: Data
var dateOfBirth: Date
}
struct Profile: Codable {
var name: String
var photo: Data
var dateOfBirth: Date
}
struct Profile: Codable {
var name: String
var photo: Data
var dateOfBirth: Date
}
extension Profile {
enum CodingKeys: String, CodingKey {
case name = "name"

case photo = "photo"
case dateOfBirth = "dateOfBirth"
}
}



struct Profile: Codable {
var name: String
var photo: Data
var dateOfBirth: Date
}
extension Profile {
enum CodingKeys: String, CodingKey {
case name = "name"

case photo = "photo"
case dateOfBirth = "dateOfBirth"
}
}



extension Profile : Decodable {
init(from decoder: Decoder) throws {
}
}
struct Profile: Codable {
var name: String
var photo: Data
var dateOfBirth: Date
}
extension Profile {
enum CodingKeys: String, CodingKey {
case name = "name"

case photo = "photo"
case dateOfBirth = "dateOfBirth"
}
}



extension Profile : Decodable {
init(from decoder: Decoder) throws {
let values = try decoder.container(keyedBy: CodingKeys.self)

}
}
struct Profile: Codable {
var name: String
var photo: Data
var dateOfBirth: Date
}
extension Profile {
enum CodingKeys: String, CodingKey {
case name = "name"

case photo = "photo"
case dateOfBirth = "dateOfBirth"
}
}



extension Profile : Decodable {
init(from decoder: Decoder) throws {
let values = try decoder.container(keyedBy: CodingKeys.self)

name = try values.decode(String.self, forKey: .name)
}
}
struct Profile: Codable {
var name: String
var photo: Data
var dateOfBirth: Date
}
extension Profile {
enum CodingKeys: String, CodingKey {
case name = "name"

case photo = "photo"
case dateOfBirth = "dateOfBirth"
}
}



extension Profile : Decodable {
init(from decoder: Decoder) throws {
let values = try decoder.container(keyedBy: CodingKeys.self)

name = try values.decode(String.self, forKey: .name)
photo = try values.decode(Data.self, forKey: .photo)
}
}
struct Profile: Codable {
var name: String
var photo: Data
var dateOfBirth: Date
}
extension Profile {
enum CodingKeys: String, CodingKey {
case name = "name"

case photo = "photo"
case dateOfBirth = "dateOfBirth"
}
}



extension Profile : Decodable {
init(from decoder: Decoder) throws {
let values = try decoder.container(keyedBy: CodingKeys.self)

name = try values.decode(String.self, forKey: .name)
photo = try values.decode(Data.self, forKey: .photo)
dateOfBirth = try values.decode(Date.self, forKey: .dateOfBirth)
}
}
struct Profile: Codable {
var name: String
var photo: Data
var dateOfBirth: Date
}
extension Profile {
enum CodingKeys: String, CodingKey {
case name = "name"

case photo = "photo"
case dateOfBirth = "dateOfBirth"
}
}



extension Profile : Encodable {
func encode(to encoder: Encoder) throws {
}
}
struct Profile: Codable {
var name: String
var photo: Data
var dateOfBirth: Date
}
extension Profile {
enum CodingKeys: String, CodingKey {
case name = "name"

case photo = "photo"
case dateOfBirth = "dateOfBirth"
}
}



extension Profile : Encodable {
func encode(to encoder: Encoder) throws {
var container = try encoder.container(keyedBy: CodingKeys.self)

}
}
struct Profile: Codable {
var name: String
var photo: Data
var dateOfBirth: Date
}
extension Profile {
enum CodingKeys: String, CodingKey {
case name = "name"

case photo = "photo"
case dateOfBirth = "dateOfBirth"
}
}



extension Profile : Encodable {
func encode(to encoder: Encoder) throws {
var container = try encoder.container(keyedBy: CodingKeys.self)

try container.encode(name, forKey: .name)
try container.encode(photo, forKey: .photo)
try container.encode(dateOfBirth, forKey: .dateOfBirth)
}
}
Body Data
{
"name": "John Doe",
"photo": "jbbkj362",
"dateOfBirth": "06-06-1980“
}
struct Profile: Codable {
var name: String
var photo: Data
var dateOfBirth: Date
}
struct Profile: Codable {
var name: String
var photo: Data
var dateOfBirth: Date
}
router.get("/profile", handler: getProfiles)
struct Profile: Codable {
var name: String
var photo: Data
var dateOfBirth: Date
}
router.get("/profile", handler: getProfiles)
func getProfiles(request: RouterRequest, response: RouterResponse, next: () -> Void) -> Void
{
}
struct Profile: Codable {
var name: String
var photo: Data
var dateOfBirth: Date
}
router.get("/profile", handler: getProfiles)
func getProfiles(request: RouterRequest, response: RouterResponse, next: () -> Void) -> Void
{
var profile = request.read(as: Profile.Type)
}
struct Profile: Codable {
var name: String
var photo: Data
var dateOfBirth: Date
}
router.get("/profile", handler: getProfiles)
func getProfiles(respondWith: @escaping ([Profile]?, Error?) -> Void) -> Void
{
}
struct Profile: Codable {
var name: String
var photo: Data
var dateOfBirth: Date
}
router.get("/profile", handler: getProfiles)
func getProfiles(respondWith: @escaping ([Profile]?, Error?) -> Void) -> Void
{
...
respondWith(profiles, nil)
}
struct Profile: Codable {
var name: String
var photo: Data
var dateOfBirth: Date
}
router.get("/profile", handler: getProfiles)
router.post("/profile", handler: addProfile)
func getProfiles(respondWith: @escaping ([Profile]?, Error?) -> Void) -> Void
{
...
respondWith(profiles, nil)
}
struct Profile: Codable {
var name: String
var photo: Data
var dateOfBirth: Date
}
router.get("/profile", handler: getProfiles)
router.post("/profile", handler: addProfile)
func getProfiles(respondWith: @escaping ([Profile]?, Error?) -> Void) -> Void
{
...
respondWith(profiles, nil)
}
func addProfile(profile: Profile, respondWith: @escaping (Profile?, Error?) -> Void) -> Void
{
...
respondWith(profile, nil)
}
guard let backend = KituraKit(baseURL: "http://localhost:8080") else {
print("Error creating KituraKit client")
return
}
backend.get("/profile") { (profiles: [Profile]?, error: RequestError?) in
...
}
KITURAKIT
Query Parameters
GET: /profile?name=“John Doe”#
{
"name": "John Doe",
"photo": "jbbkj362",
"dateOfBirth": "06-06-1980“
}
{"name": "John Doe","photo": "jbbkj362","dateOfBirth": "06-06-1980"}
{"name": "John Doe" }
{"name": "John Doe"}
{“name"= "John Doe"}
{ name = "John Doe"}
? name = "John Doe"}
? name = "John Doe"#
?name="John Doe"#
struct Profile: Codable {
var name: String
var photo: Data
var dateOfBirth: Date
}
router.get("/profile", handler: getProfiles)
func getProfiles(respondWith: @escaping ([Profile]?, Error?) -> Void) -> Void
{
...
respondWith(profiles, nil)
}
struct Profile: Codable {
var name: String
var photo: Data
var dateOfBirth: Date
}
struct Query: QueryParams {
var name: String
}
router.get("/profile", handler: getProfiles)
func getProfiles(respondWith: @escaping ([Profile]?, Error?) -> Void) -> Void
{
...
respondWith(profiles, nil)
}
struct Profile: Codable {
var name: String
var photo: Data
var dateOfBirth: Date
}
struct Query: QueryParams {
var name: String
}
router.get("/profile", handler: getProfiles)
func getProfiles( , respondWith: @escaping ([Profile]?, Error?) -> Void) -> Void
{
...
respondWith(profiles, nil)
}
struct Profile: Codable {
var name: String
var photo: Data
var dateOfBirth: Date
}
struct Query: QueryParams {
var name: String
}
router.get("/profile", handler: getProfiles)
func getProfiles(query: Query, respondWith: @escaping ([Profile]?, Error?) -> Void) -> Void
{
...
respondWith(profiles, nil)
}
struct Profile: Codable {
var name: String
var photo: Data
var dateOfBirth: Date
}
struct Query: QueryParams {
var name: String
}
router.get("/profile", handler: getProfiles)
func getProfiles(query: Query, respondWith: @escaping ([Profile]?, Error?) -> Void) -> Void
{
...
respondWith(profiles , nil)
}
struct Profile: Codable {
var name: String
var photo: Data
var dateOfBirth: Date
}
struct Query: QueryParams {
var name: String
}
router.get("/profile", handler: getProfiles)
func getProfiles(query: Query, respondWith: @escaping ([Profile]?, Error?) -> Void) -> Void
{
...
respondWith(profiles.filter{ ($0.name == query.name), nil)
}
What Else?
SELECT * from Profiles
name,, photo, dateOfBirth,
"John Doe", "jbbkj362", "06-06-1980",
name,, photo, dateOfBirth
"John Doe", "jbbkj362", "06-06-1980"
name:”John Doe”,photo:”jbbkj362”,dateOfBirth:”06-06-1980"
{name:”John Doe”,photo:”jbbkj362”,dateOfBirth:”06-06-1980”}
struct Profile: Codable {
var name: String
var photo: Data
var dateOfBirth: Date
}
router.get("/profile", handler: getProfiles)
func getProfiles(respondWith: @escaping ([Profile]?, Error?) -> Void) -> Void
{
...
respondWith(profiles, nil)
}
struct Profile: Model {
var name: String
var photo: Data
var dateOfBirth: Date
}
router.get("/profile", handler: getProfiles)
func getProfiles(respondWith: @escaping ([Profile]?, Error?) -> Void) -> Void
{
...
respondWith(profiles, nil)
}
struct Profile: Model {
var name: String
var photo: Data
var dateOfBirth: Date
}
router.get("/profile", handler: getProfiles)
func getProfiles(respondWith: @escaping ([Profile]?, Error?) -> Void) -> Void
{
Profile.getAll()
respondWith(profiles, nil)
}
struct Profile: Model {
var name: String
var photo: Data
var dateOfBirth: Date
}
router.get("/profile", handler: getProfiles)
func getProfiles(respondWith: @escaping ([Profile]?, Error?) -> Void) -> Void
{
Profile.getAll(respondWith)
respondWith(profiles, nil)
}
struct Profile: Model {
var name: String
var photo: Data
var dateOfBirth: Date
}
router.get("/profile", handler: getProfiles)
func getProfiles(respondWith: @escaping ([Profile]?, Error?) -> Void) -> Void
{
Profile.getAll(respondWith)
}
struct Profile: Model {
var name: String
var photo: Data
var dateOfBirth: Date
}
router.get("/profile", handler: getProfiles)
func getProfiles(completion: @escaping ([Profile]?, Error?) -> Void) -> Void
{
Profile.getAll(completion)
}
SELECT * from Profiles
SELECT * from Profiles
SELECT * from Profiles WHERE name = “John Doe”
struct Profile: Model {
var name: String
var photo: Data
var dateOfBirth: Date
}
router.get("/profile", handler: getProfiles)
func getProfiles(completion: @escaping ([Profile]?, Error?) -> Void) -> Void
{
Profile.getAll(completion)
}
struct Profile: Model {
var name: String
var photo: Data
var dateOfBirth: Date
}
struct Query: QueryParams {
var name: String
}
router.get("/profile", handler: getProfiles)
func getProfiles(completion: @escaping ([Profile]?, Error?) -> Void) -> Void
{
Profile.getAll(completion)
}
struct Profile: Model {
var name: String
var photo: Data
var dateOfBirth: Date
}
struct Query: QueryParams {
var name: String
}
router.get("/profile", handler: getProfiles)
func getProfiles(query: Query, completion: @escaping ([Profile]?, Error?) -> Void) -> Void
{
Profile.getAll(completion)
}
struct Profile: Model {
var name: String
var photo: Data
var dateOfBirth: Date
}
struct Query: QueryParams {
var name: String
}
router.get("/profile", handler: getProfiles)
func getProfiles(query: Query, completion: @escaping ([Profile]?, Error?) -> Void) -> Void
{
Profile.getAll( completion)
}
struct Profile: Model {
var name: String
var photo: Data
var dateOfBirth: Date
}
struct Query: QueryParams {
var name: String
}
router.get("/profile", handler: getProfiles)
func getProfiles(query: Query, completion: @escaping ([Profile]?, Error?) -> Void) -> Void
{
Profile.getAll(matching: query, completion)
}
Codable
Dynamic Swift
Questions
Ad

Recommended

MongoDB (Advanced)
MongoDB (Advanced)
TO THE NEW | Technology
 
Schema design short
Schema design short
MongoDB
 
MongoDB For C++ Developers
MongoDB For C++ Developers
Ynon Perek
 
Introduction to py2neo
Introduction to py2neo
Nigel Small
 
Try!Swift India 2017: All you need is Swift
Try!Swift India 2017: All you need is Swift
Chris Bailey
 
Swift & JSON
Swift & JSON
John Sundell
 
Talk Binary to Me
Talk Binary to Me
Maxim Zaks
 
Persistence And Documents
Persistence And Documents
SV.CO
 
Intermediate Swift Language by Apple
Intermediate Swift Language by Apple
jamesfeng2
 
Swift 4 : Codable
Swift 4 : Codable
SeongGyu Jo
 
AltConf 2015: Swift Thinking
AltConf 2015: Swift Thinking
Natasha Murashev
 
Swift - 혼자 공부하면 분명히 안할테니까 같이 공부하기
Swift - 혼자 공부하면 분명히 안할테니까 같이 공부하기
Suyeol Jeon
 
Introduction to Swift programming language.
Introduction to Swift programming language.
Icalia Labs
 
An introduction to functional programming with Swift
An introduction to functional programming with Swift
Fatih Nayebi, Ph.D.
 
Working with the Web: 
Decoding JSON
Working with the Web: 
Decoding JSON
SV.CO
 
Value protocols and codables
Value protocols and codables
Florent Vilmart
 
Codable routing
Codable routing
Pushkar Kulkarni
 
7 Habits For a More Functional Swift
7 Habits For a More Functional Swift
Jason Larsen
 
Swift School #1
Swift School #1
Sergey Pronin
 
NodeJS Interactive 2019: FaaS meets Frameworks
NodeJS Interactive 2019: FaaS meets Frameworks
Chris Bailey
 
Voxxed Micro-services: Serverless JakartaEE - JAX-RS comes to FaaS
Voxxed Micro-services: Serverless JakartaEE - JAX-RS comes to FaaS
Chris Bailey
 
Silicon Valley Code Camp 2019 - Reaching the Cloud Native World
Silicon Valley Code Camp 2019 - Reaching the Cloud Native World
Chris Bailey
 
FaaS Meets Java EE: Developing Cloud Native Applications at Speed
FaaS Meets Java EE: Developing Cloud Native Applications at Speed
Chris Bailey
 
AltConf 2019: Server-Side Swift State of the Union
AltConf 2019: Server-Side Swift State of the Union
Chris Bailey
 
Server-side Swift with Swagger
Server-side Swift with Swagger
Chris Bailey
 
Node Summit 2018: Cloud Native Node.js
Node Summit 2018: Cloud Native Node.js
Chris Bailey
 
Index - BFFs vs GraphQL
Index - BFFs vs GraphQL
Chris Bailey
 
Swift Cloud Workshop - Swift Microservices
Swift Cloud Workshop - Swift Microservices
Chris Bailey
 
Swift Summit 2017: Server Swift State of the Union
Swift Summit 2017: Server Swift State of the Union
Chris Bailey
 
IBM Cloud University: Build, Deploy and Scale Node.js Microservices
IBM Cloud University: Build, Deploy and Scale Node.js Microservices
Chris Bailey
 

More Related Content

Similar to Swift Cloud Workshop - Codable, the key to Fullstack Swift (11)

Intermediate Swift Language by Apple
Intermediate Swift Language by Apple
jamesfeng2
 
Swift 4 : Codable
Swift 4 : Codable
SeongGyu Jo
 
AltConf 2015: Swift Thinking
AltConf 2015: Swift Thinking
Natasha Murashev
 
Swift - 혼자 공부하면 분명히 안할테니까 같이 공부하기
Swift - 혼자 공부하면 분명히 안할테니까 같이 공부하기
Suyeol Jeon
 
Introduction to Swift programming language.
Introduction to Swift programming language.
Icalia Labs
 
An introduction to functional programming with Swift
An introduction to functional programming with Swift
Fatih Nayebi, Ph.D.
 
Working with the Web: 
Decoding JSON
Working with the Web: 
Decoding JSON
SV.CO
 
Value protocols and codables
Value protocols and codables
Florent Vilmart
 
Codable routing
Codable routing
Pushkar Kulkarni
 
7 Habits For a More Functional Swift
7 Habits For a More Functional Swift
Jason Larsen
 
Swift School #1
Swift School #1
Sergey Pronin
 
Intermediate Swift Language by Apple
Intermediate Swift Language by Apple
jamesfeng2
 
Swift 4 : Codable
Swift 4 : Codable
SeongGyu Jo
 
AltConf 2015: Swift Thinking
AltConf 2015: Swift Thinking
Natasha Murashev
 
Swift - 혼자 공부하면 분명히 안할테니까 같이 공부하기
Swift - 혼자 공부하면 분명히 안할테니까 같이 공부하기
Suyeol Jeon
 
Introduction to Swift programming language.
Introduction to Swift programming language.
Icalia Labs
 
An introduction to functional programming with Swift
An introduction to functional programming with Swift
Fatih Nayebi, Ph.D.
 
Working with the Web: 
Decoding JSON
Working with the Web: 
Decoding JSON
SV.CO
 
Value protocols and codables
Value protocols and codables
Florent Vilmart
 
7 Habits For a More Functional Swift
7 Habits For a More Functional Swift
Jason Larsen
 

More from Chris Bailey (20)

NodeJS Interactive 2019: FaaS meets Frameworks
NodeJS Interactive 2019: FaaS meets Frameworks
Chris Bailey
 
Voxxed Micro-services: Serverless JakartaEE - JAX-RS comes to FaaS
Voxxed Micro-services: Serverless JakartaEE - JAX-RS comes to FaaS
Chris Bailey
 
Silicon Valley Code Camp 2019 - Reaching the Cloud Native World
Silicon Valley Code Camp 2019 - Reaching the Cloud Native World
Chris Bailey
 
FaaS Meets Java EE: Developing Cloud Native Applications at Speed
FaaS Meets Java EE: Developing Cloud Native Applications at Speed
Chris Bailey
 
AltConf 2019: Server-Side Swift State of the Union
AltConf 2019: Server-Side Swift State of the Union
Chris Bailey
 
Server-side Swift with Swagger
Server-side Swift with Swagger
Chris Bailey
 
Node Summit 2018: Cloud Native Node.js
Node Summit 2018: Cloud Native Node.js
Chris Bailey
 
Index - BFFs vs GraphQL
Index - BFFs vs GraphQL
Chris Bailey
 
Swift Cloud Workshop - Swift Microservices
Swift Cloud Workshop - Swift Microservices
Chris Bailey
 
Swift Summit 2017: Server Swift State of the Union
Swift Summit 2017: Server Swift State of the Union
Chris Bailey
 
IBM Cloud University: Build, Deploy and Scale Node.js Microservices
IBM Cloud University: Build, Deploy and Scale Node.js Microservices
Chris Bailey
 
IBM Cloud University: Java, Node.js and Swift
IBM Cloud University: Java, Node.js and Swift
Chris Bailey
 
Node Interactive: Node.js Performance and Highly Scalable Micro-Services
Node Interactive: Node.js Performance and Highly Scalable Micro-Services
Chris Bailey
 
FrenchKit 2017: Server(less) Swift
FrenchKit 2017: Server(less) Swift
Chris Bailey
 
AltConf 2017: Full Stack Swift in 30 Minutes
AltConf 2017: Full Stack Swift in 30 Minutes
Chris Bailey
 
InterConnect: Server Side Swift for Java Developers
InterConnect: Server Side Swift for Java Developers
Chris Bailey
 
InterConnect: Java, Node.js and Swift - Which, Why and When
InterConnect: Java, Node.js and Swift - Which, Why and When
Chris Bailey
 
Playgrounds: Mobile + Swift = BFF
Playgrounds: Mobile + Swift = BFF
Chris Bailey
 
Swift Summit: Pushing the boundaries of Swift to the Server
Swift Summit: Pushing the boundaries of Swift to the Server
Chris Bailey
 
O'Reilly Software Architecture Conf: Cloud Economics
O'Reilly Software Architecture Conf: Cloud Economics
Chris Bailey
 
NodeJS Interactive 2019: FaaS meets Frameworks
NodeJS Interactive 2019: FaaS meets Frameworks
Chris Bailey
 
Voxxed Micro-services: Serverless JakartaEE - JAX-RS comes to FaaS
Voxxed Micro-services: Serverless JakartaEE - JAX-RS comes to FaaS
Chris Bailey
 
Silicon Valley Code Camp 2019 - Reaching the Cloud Native World
Silicon Valley Code Camp 2019 - Reaching the Cloud Native World
Chris Bailey
 
FaaS Meets Java EE: Developing Cloud Native Applications at Speed
FaaS Meets Java EE: Developing Cloud Native Applications at Speed
Chris Bailey
 
AltConf 2019: Server-Side Swift State of the Union
AltConf 2019: Server-Side Swift State of the Union
Chris Bailey
 
Server-side Swift with Swagger
Server-side Swift with Swagger
Chris Bailey
 
Node Summit 2018: Cloud Native Node.js
Node Summit 2018: Cloud Native Node.js
Chris Bailey
 
Index - BFFs vs GraphQL
Index - BFFs vs GraphQL
Chris Bailey
 
Swift Cloud Workshop - Swift Microservices
Swift Cloud Workshop - Swift Microservices
Chris Bailey
 
Swift Summit 2017: Server Swift State of the Union
Swift Summit 2017: Server Swift State of the Union
Chris Bailey
 
IBM Cloud University: Build, Deploy and Scale Node.js Microservices
IBM Cloud University: Build, Deploy and Scale Node.js Microservices
Chris Bailey
 
IBM Cloud University: Java, Node.js and Swift
IBM Cloud University: Java, Node.js and Swift
Chris Bailey
 
Node Interactive: Node.js Performance and Highly Scalable Micro-Services
Node Interactive: Node.js Performance and Highly Scalable Micro-Services
Chris Bailey
 
FrenchKit 2017: Server(less) Swift
FrenchKit 2017: Server(less) Swift
Chris Bailey
 
AltConf 2017: Full Stack Swift in 30 Minutes
AltConf 2017: Full Stack Swift in 30 Minutes
Chris Bailey
 
InterConnect: Server Side Swift for Java Developers
InterConnect: Server Side Swift for Java Developers
Chris Bailey
 
InterConnect: Java, Node.js and Swift - Which, Why and When
InterConnect: Java, Node.js and Swift - Which, Why and When
Chris Bailey
 
Playgrounds: Mobile + Swift = BFF
Playgrounds: Mobile + Swift = BFF
Chris Bailey
 
Swift Summit: Pushing the boundaries of Swift to the Server
Swift Summit: Pushing the boundaries of Swift to the Server
Chris Bailey
 
O'Reilly Software Architecture Conf: Cloud Economics
O'Reilly Software Architecture Conf: Cloud Economics
Chris Bailey
 
Ad

Recently uploaded (20)

CodeCleaner: Mitigating Data Contamination for LLM Benchmarking
CodeCleaner: Mitigating Data Contamination for LLM Benchmarking
arabelatso
 
Test Case Design Techniques – Practical Examples & Best Practices in Software...
Test Case Design Techniques – Practical Examples & Best Practices in Software...
Muhammad Fahad Bashir
 
Folding Cheat Sheet # 9 - List Unfolding 𝑢𝑛𝑓𝑜𝑙𝑑 as the Computational Dual of ...
Folding Cheat Sheet # 9 - List Unfolding 𝑢𝑛𝑓𝑜𝑙𝑑 as the Computational Dual of ...
Philip Schwarz
 
Microsoft-365-Administrator-s-Guide1.pdf
Microsoft-365-Administrator-s-Guide1.pdf
mazharatknl
 
Heat Treatment Process Automation in India
Heat Treatment Process Automation in India
Reckers Mechatronics
 
Best Practice for LLM Serving in the Cloud
Best Practice for LLM Serving in the Cloud
Alluxio, Inc.
 
Digital Transformation: Automating the Placement of Medical Interns
Digital Transformation: Automating the Placement of Medical Interns
Safe Software
 
CodeCleaner: Mitigating Data Contamination for LLM Benchmarking
CodeCleaner: Mitigating Data Contamination for LLM Benchmarking
arabelatso
 
Y - Recursion The Hard Way GopherCon EU 2025
Y - Recursion The Hard Way GopherCon EU 2025
Eleanor McHugh
 
On-Device AI: Is It Time to Go All-In, or Do We Still Need the Cloud?
On-Device AI: Is It Time to Go All-In, or Do We Still Need the Cloud?
Hassan Abid
 
A Guide to Telemedicine Software Development.pdf
A Guide to Telemedicine Software Development.pdf
Olivero Bozzelli
 
Decipher SEO Solutions for your startup needs.
Decipher SEO Solutions for your startup needs.
mathai2
 
Enable Your Cloud Journey With Microsoft Trusted Partner | IFI Tech
Enable Your Cloud Journey With Microsoft Trusted Partner | IFI Tech
IFI Techsolutions
 
Milwaukee Marketo User Group June 2025 - Optimize and Enhance Efficiency - Sm...
Milwaukee Marketo User Group June 2025 - Optimize and Enhance Efficiency - Sm...
BradBedford3
 
Why Every Growing Business Needs a Staff Augmentation Company IN USA.pdf
Why Every Growing Business Needs a Staff Augmentation Company IN USA.pdf
mary rojas
 
SAP PM Module Level-IV Training Complete.ppt
SAP PM Module Level-IV Training Complete.ppt
MuhammadShaheryar36
 
Zoho Creator Solution for EI by Elsner Technologies.docx
Zoho Creator Solution for EI by Elsner Technologies.docx
Elsner Technologies Pvt. Ltd.
 
Application Modernization with Choreo - The AI-Native Internal Developer Plat...
Application Modernization with Choreo - The AI-Native Internal Developer Plat...
WSO2
 
Advance Doctor Appointment Booking App With Online Payment
Advance Doctor Appointment Booking App With Online Payment
AxisTechnolabs
 
Which Hiring Management Tools Offer the Best ROI?
Which Hiring Management Tools Offer the Best ROI?
HireME
 
CodeCleaner: Mitigating Data Contamination for LLM Benchmarking
CodeCleaner: Mitigating Data Contamination for LLM Benchmarking
arabelatso
 
Test Case Design Techniques – Practical Examples & Best Practices in Software...
Test Case Design Techniques – Practical Examples & Best Practices in Software...
Muhammad Fahad Bashir
 
Folding Cheat Sheet # 9 - List Unfolding 𝑢𝑛𝑓𝑜𝑙𝑑 as the Computational Dual of ...
Folding Cheat Sheet # 9 - List Unfolding 𝑢𝑛𝑓𝑜𝑙𝑑 as the Computational Dual of ...
Philip Schwarz
 
Microsoft-365-Administrator-s-Guide1.pdf
Microsoft-365-Administrator-s-Guide1.pdf
mazharatknl
 
Heat Treatment Process Automation in India
Heat Treatment Process Automation in India
Reckers Mechatronics
 
Best Practice for LLM Serving in the Cloud
Best Practice for LLM Serving in the Cloud
Alluxio, Inc.
 
Digital Transformation: Automating the Placement of Medical Interns
Digital Transformation: Automating the Placement of Medical Interns
Safe Software
 
CodeCleaner: Mitigating Data Contamination for LLM Benchmarking
CodeCleaner: Mitigating Data Contamination for LLM Benchmarking
arabelatso
 
Y - Recursion The Hard Way GopherCon EU 2025
Y - Recursion The Hard Way GopherCon EU 2025
Eleanor McHugh
 
On-Device AI: Is It Time to Go All-In, or Do We Still Need the Cloud?
On-Device AI: Is It Time to Go All-In, or Do We Still Need the Cloud?
Hassan Abid
 
A Guide to Telemedicine Software Development.pdf
A Guide to Telemedicine Software Development.pdf
Olivero Bozzelli
 
Decipher SEO Solutions for your startup needs.
Decipher SEO Solutions for your startup needs.
mathai2
 
Enable Your Cloud Journey With Microsoft Trusted Partner | IFI Tech
Enable Your Cloud Journey With Microsoft Trusted Partner | IFI Tech
IFI Techsolutions
 
Milwaukee Marketo User Group June 2025 - Optimize and Enhance Efficiency - Sm...
Milwaukee Marketo User Group June 2025 - Optimize and Enhance Efficiency - Sm...
BradBedford3
 
Why Every Growing Business Needs a Staff Augmentation Company IN USA.pdf
Why Every Growing Business Needs a Staff Augmentation Company IN USA.pdf
mary rojas
 
SAP PM Module Level-IV Training Complete.ppt
SAP PM Module Level-IV Training Complete.ppt
MuhammadShaheryar36
 
Zoho Creator Solution for EI by Elsner Technologies.docx
Zoho Creator Solution for EI by Elsner Technologies.docx
Elsner Technologies Pvt. Ltd.
 
Application Modernization with Choreo - The AI-Native Internal Developer Plat...
Application Modernization with Choreo - The AI-Native Internal Developer Plat...
WSO2
 
Advance Doctor Appointment Booking App With Online Payment
Advance Doctor Appointment Booking App With Online Payment
AxisTechnolabs
 
Which Hiring Management Tools Offer the Best ROI?
Which Hiring Management Tools Offer the Best ROI?
HireME
 
Ad

Swift Cloud Workshop - Codable, the key to Fullstack Swift

  • 1. Codable
 The key to Fullstack Swift Swift Cloud Workshop 3
 February 23rd, 2018 Chris Bailey
 (@Chris__Bailey)
  • 3. struct Profile { var name: String var photo: Data var dateOfBirth: Date } let profile = Profile(name: “Chris”, photo: image, dateOfBirth: Date(“06-06-1980”))
  • 4. struct Profile : Codable { var name: String var photo: Data var dateOfBirth: Date } let profile = Profile(name: “Chris”, photo: image, dateOfBirth: Date(“06-06-1980”))
  • 5. struct Profile : Codable { var name: String var photo: Data var dateOfBirth: Date } let profile = Profile(name: “Chris”, photo: image, dateOfBirth: Date(“06-06-1980”)) let encoder = JSONEncoder() let jsonData = try encoder.encode(profile)
  • 6. struct Profile : Codable { var name: String var photo: Data var dateOfBirth: Date } let profile = Profile(name: “Chris”, photo: image, dateOfBirth: Date(“06-06-1980”)) let encoder = JSONEncoder() let jsonData = try encoder.encode(profile) let decoder = JSONDecoder() let person = try decoder.decode(Profile.self, from: jsonData)
  • 8. { "name": "", "photo": "", "dateOfBirth": "" } { "name": "", "photo": "", "dateOfBirth": { "year": "month": "day": } } struct Profile { var name: String var photo: Data var dateOfBirth: Date } Swift var profile: [String : Any] Swift KITURA
  • 9. let profile = Profile(name: name, photo: photo)let json = JSON(data: data)
 guard json["name"].exists() else { response.status(.unprocessableEntity) response.send(json: JSON([ "error": "Missing reqired property `name`" ])) next() } guard let photo = Data(base64Encoded: photoString) else { response.status(.unprocessableEntity) response.send(json: JSON([ "error": "Type mismatch, `photo` expected to be Base64 encoded data" ])) next() } guard let name = json["name"].string else { response.status(.unprocessableEntity) response.send(json: JSON([ "error": "Type mismatch, `name` expected to be a String" ])) next() } guard json["photo"].exists() else { response.status(.unprocessableEntity) response.send(json: JSON([ "error": "Missing reqired property photo`" ])) next() } guard let photoString = json[“photo"].string else { response.status(.unprocessableEntity) response.send(json: JSON([ "error": "Type mismatch, `photo` expected to be a String" ])) next() }
  • 16. struct Profile { var name: String var photo: Data var dateOfBirth: Date } Swift
  • 17. struct Profile { var name: String var photo: Data var dateOfBirth: Date } Swift Swift KITURA
  • 18. struct Profile: Codable { var name: String var photo: Data var dateOfBirth: Date } Swift Swift KITURA
  • 19. struct Profile: Codable { var name: String var photo: Data var dateOfBirth: Date } Swift Swift struct Profile: Codable { var name: String var photo: Data var dateOfBirth: Date } KITURA
  • 20. struct Profile: Codable { var name: String var photo: Data var dateOfBirth: Date } Swift Swift struct Profile: Codable { var name: String var photo: Data var dateOfBirth: Date } let encoder = JSONEncoder() let data = try encoder.encode(profile) KITURA
  • 21. struct Profile: Codable { var name: String var photo: Data var dateOfBirth: Date } Swift Swift struct Profile: Codable { var name: String var photo: Data var dateOfBirth: Date } let decoder = JSONDecoder() let person = try decoder.decode(Person.self, from: jsonData) KITURA
  • 22. { "name": "", "photo": "", "dateOfBirth": "" } { "name": "", "photo": "", "dateOfBirth": "" } struct Profile: Codable { var name: String var photo: Data var dateOfBirth: Date } Swift Swift struct Profile: Codable { var name: String var photo: Data var dateOfBirth: Date } KITURA
  • 23. struct Profile: Codable { var name: String var photo: Data var dateOfBirth: Date } Swift Swift struct Profile: Codable { var name: String var photo: Data var dateOfBirth: Date } KITURA
  • 24. struct Profile: Codable { var name: String var photo: Data var dateOfBirth: Date } Swift Swift struct Profile: Codable { var name: String var photo: Data var dateOfBirth: Date } KITURA
  • 25. struct Profile: Codable { var name: String var photo: Data var dateOfBirth: Date } Swift Swift struct Profile: Codable { var name: String var photo: Data var dateOfBirth: Date } KITURA
  • 27. struct Profile { var name: String var photo: Data var dateOfBirth: Date }
  • 28. struct Profile: Codable { var name: String var photo: Data var dateOfBirth: Date }
  • 29. struct Profile: Codable { var name: String var photo: Data var dateOfBirth: Date } extension Profile { enum CodingKeys: String, CodingKey { case name = "name"
 case photo = "photo" case dateOfBirth = "dateOfBirth" } }
 

  • 30. struct Profile: Codable { var name: String var photo: Data var dateOfBirth: Date } extension Profile { enum CodingKeys: String, CodingKey { case name = "name"
 case photo = "photo" case dateOfBirth = "dateOfBirth" } }
 
 extension Profile : Decodable { init(from decoder: Decoder) throws { } }
  • 31. struct Profile: Codable { var name: String var photo: Data var dateOfBirth: Date } extension Profile { enum CodingKeys: String, CodingKey { case name = "name"
 case photo = "photo" case dateOfBirth = "dateOfBirth" } }
 
 extension Profile : Decodable { init(from decoder: Decoder) throws { let values = try decoder.container(keyedBy: CodingKeys.self)
 } }
  • 32. struct Profile: Codable { var name: String var photo: Data var dateOfBirth: Date } extension Profile { enum CodingKeys: String, CodingKey { case name = "name"
 case photo = "photo" case dateOfBirth = "dateOfBirth" } }
 
 extension Profile : Decodable { init(from decoder: Decoder) throws { let values = try decoder.container(keyedBy: CodingKeys.self)
 name = try values.decode(String.self, forKey: .name) } }
  • 33. struct Profile: Codable { var name: String var photo: Data var dateOfBirth: Date } extension Profile { enum CodingKeys: String, CodingKey { case name = "name"
 case photo = "photo" case dateOfBirth = "dateOfBirth" } }
 
 extension Profile : Decodable { init(from decoder: Decoder) throws { let values = try decoder.container(keyedBy: CodingKeys.self)
 name = try values.decode(String.self, forKey: .name) photo = try values.decode(Data.self, forKey: .photo) } }
  • 34. struct Profile: Codable { var name: String var photo: Data var dateOfBirth: Date } extension Profile { enum CodingKeys: String, CodingKey { case name = "name"
 case photo = "photo" case dateOfBirth = "dateOfBirth" } }
 
 extension Profile : Decodable { init(from decoder: Decoder) throws { let values = try decoder.container(keyedBy: CodingKeys.self)
 name = try values.decode(String.self, forKey: .name) photo = try values.decode(Data.self, forKey: .photo) dateOfBirth = try values.decode(Date.self, forKey: .dateOfBirth) } }
  • 35. struct Profile: Codable { var name: String var photo: Data var dateOfBirth: Date } extension Profile { enum CodingKeys: String, CodingKey { case name = "name"
 case photo = "photo" case dateOfBirth = "dateOfBirth" } }
 
 extension Profile : Encodable { func encode(to encoder: Encoder) throws { } }
  • 36. struct Profile: Codable { var name: String var photo: Data var dateOfBirth: Date } extension Profile { enum CodingKeys: String, CodingKey { case name = "name"
 case photo = "photo" case dateOfBirth = "dateOfBirth" } }
 
 extension Profile : Encodable { func encode(to encoder: Encoder) throws { var container = try encoder.container(keyedBy: CodingKeys.self)
 } }
  • 37. struct Profile: Codable { var name: String var photo: Data var dateOfBirth: Date } extension Profile { enum CodingKeys: String, CodingKey { case name = "name"
 case photo = "photo" case dateOfBirth = "dateOfBirth" } }
 
 extension Profile : Encodable { func encode(to encoder: Encoder) throws { var container = try encoder.container(keyedBy: CodingKeys.self)
 try container.encode(name, forKey: .name) try container.encode(photo, forKey: .photo) try container.encode(dateOfBirth, forKey: .dateOfBirth) } }
  • 39. { "name": "John Doe", "photo": "jbbkj362", "dateOfBirth": "06-06-1980“ }
  • 40. struct Profile: Codable { var name: String var photo: Data var dateOfBirth: Date }
  • 41. struct Profile: Codable { var name: String var photo: Data var dateOfBirth: Date } router.get("/profile", handler: getProfiles)
  • 42. struct Profile: Codable { var name: String var photo: Data var dateOfBirth: Date } router.get("/profile", handler: getProfiles) func getProfiles(request: RouterRequest, response: RouterResponse, next: () -> Void) -> Void { }
  • 43. struct Profile: Codable { var name: String var photo: Data var dateOfBirth: Date } router.get("/profile", handler: getProfiles) func getProfiles(request: RouterRequest, response: RouterResponse, next: () -> Void) -> Void { var profile = request.read(as: Profile.Type) }
  • 44. struct Profile: Codable { var name: String var photo: Data var dateOfBirth: Date } router.get("/profile", handler: getProfiles) func getProfiles(respondWith: @escaping ([Profile]?, Error?) -> Void) -> Void { }
  • 45. struct Profile: Codable { var name: String var photo: Data var dateOfBirth: Date } router.get("/profile", handler: getProfiles) func getProfiles(respondWith: @escaping ([Profile]?, Error?) -> Void) -> Void { ... respondWith(profiles, nil) }
  • 46. struct Profile: Codable { var name: String var photo: Data var dateOfBirth: Date } router.get("/profile", handler: getProfiles) router.post("/profile", handler: addProfile) func getProfiles(respondWith: @escaping ([Profile]?, Error?) -> Void) -> Void { ... respondWith(profiles, nil) }
  • 47. struct Profile: Codable { var name: String var photo: Data var dateOfBirth: Date } router.get("/profile", handler: getProfiles) router.post("/profile", handler: addProfile) func getProfiles(respondWith: @escaping ([Profile]?, Error?) -> Void) -> Void { ... respondWith(profiles, nil) } func addProfile(profile: Profile, respondWith: @escaping (Profile?, Error?) -> Void) -> Void { ... respondWith(profile, nil) }
  • 48. guard let backend = KituraKit(baseURL: "http://localhost:8080") else { print("Error creating KituraKit client") return } backend.get("/profile") { (profiles: [Profile]?, error: RequestError?) in ... } KITURAKIT
  • 51. { "name": "John Doe", "photo": "jbbkj362", "dateOfBirth": "06-06-1980“ }
  • 52. {"name": "John Doe","photo": "jbbkj362","dateOfBirth": "06-06-1980"}
  • 56. { name = "John Doe"}
  • 57. ? name = "John Doe"}
  • 58. ? name = "John Doe"#
  • 60. struct Profile: Codable { var name: String var photo: Data var dateOfBirth: Date } router.get("/profile", handler: getProfiles) func getProfiles(respondWith: @escaping ([Profile]?, Error?) -> Void) -> Void { ... respondWith(profiles, nil) }
  • 61. struct Profile: Codable { var name: String var photo: Data var dateOfBirth: Date } struct Query: QueryParams { var name: String } router.get("/profile", handler: getProfiles) func getProfiles(respondWith: @escaping ([Profile]?, Error?) -> Void) -> Void { ... respondWith(profiles, nil) }
  • 62. struct Profile: Codable { var name: String var photo: Data var dateOfBirth: Date } struct Query: QueryParams { var name: String } router.get("/profile", handler: getProfiles) func getProfiles( , respondWith: @escaping ([Profile]?, Error?) -> Void) -> Void { ... respondWith(profiles, nil) }
  • 63. struct Profile: Codable { var name: String var photo: Data var dateOfBirth: Date } struct Query: QueryParams { var name: String } router.get("/profile", handler: getProfiles) func getProfiles(query: Query, respondWith: @escaping ([Profile]?, Error?) -> Void) -> Void { ... respondWith(profiles, nil) }
  • 64. struct Profile: Codable { var name: String var photo: Data var dateOfBirth: Date } struct Query: QueryParams { var name: String } router.get("/profile", handler: getProfiles) func getProfiles(query: Query, respondWith: @escaping ([Profile]?, Error?) -> Void) -> Void { ... respondWith(profiles , nil) }
  • 65. struct Profile: Codable { var name: String var photo: Data var dateOfBirth: Date } struct Query: QueryParams { var name: String } router.get("/profile", handler: getProfiles) func getProfiles(query: Query, respondWith: @escaping ([Profile]?, Error?) -> Void) -> Void { ... respondWith(profiles.filter{ ($0.name == query.name), nil) }
  • 67. SELECT * from Profiles
  • 68. name,, photo, dateOfBirth, "John Doe", "jbbkj362", "06-06-1980",
  • 69. name,, photo, dateOfBirth "John Doe", "jbbkj362", "06-06-1980"
  • 72. struct Profile: Codable { var name: String var photo: Data var dateOfBirth: Date } router.get("/profile", handler: getProfiles) func getProfiles(respondWith: @escaping ([Profile]?, Error?) -> Void) -> Void { ... respondWith(profiles, nil) }
  • 73. struct Profile: Model { var name: String var photo: Data var dateOfBirth: Date } router.get("/profile", handler: getProfiles) func getProfiles(respondWith: @escaping ([Profile]?, Error?) -> Void) -> Void { ... respondWith(profiles, nil) }
  • 74. struct Profile: Model { var name: String var photo: Data var dateOfBirth: Date } router.get("/profile", handler: getProfiles) func getProfiles(respondWith: @escaping ([Profile]?, Error?) -> Void) -> Void { Profile.getAll() respondWith(profiles, nil) }
  • 75. struct Profile: Model { var name: String var photo: Data var dateOfBirth: Date } router.get("/profile", handler: getProfiles) func getProfiles(respondWith: @escaping ([Profile]?, Error?) -> Void) -> Void { Profile.getAll(respondWith) respondWith(profiles, nil) }
  • 76. struct Profile: Model { var name: String var photo: Data var dateOfBirth: Date } router.get("/profile", handler: getProfiles) func getProfiles(respondWith: @escaping ([Profile]?, Error?) -> Void) -> Void { Profile.getAll(respondWith) }
  • 77. struct Profile: Model { var name: String var photo: Data var dateOfBirth: Date } router.get("/profile", handler: getProfiles) func getProfiles(completion: @escaping ([Profile]?, Error?) -> Void) -> Void { Profile.getAll(completion) }
  • 78. SELECT * from Profiles
  • 79. SELECT * from Profiles
  • 80. SELECT * from Profiles WHERE name = “John Doe”
  • 81. struct Profile: Model { var name: String var photo: Data var dateOfBirth: Date } router.get("/profile", handler: getProfiles) func getProfiles(completion: @escaping ([Profile]?, Error?) -> Void) -> Void { Profile.getAll(completion) }
  • 82. struct Profile: Model { var name: String var photo: Data var dateOfBirth: Date } struct Query: QueryParams { var name: String } router.get("/profile", handler: getProfiles) func getProfiles(completion: @escaping ([Profile]?, Error?) -> Void) -> Void { Profile.getAll(completion) }
  • 83. struct Profile: Model { var name: String var photo: Data var dateOfBirth: Date } struct Query: QueryParams { var name: String } router.get("/profile", handler: getProfiles) func getProfiles(query: Query, completion: @escaping ([Profile]?, Error?) -> Void) -> Void { Profile.getAll(completion) }
  • 84. struct Profile: Model { var name: String var photo: Data var dateOfBirth: Date } struct Query: QueryParams { var name: String } router.get("/profile", handler: getProfiles) func getProfiles(query: Query, completion: @escaping ([Profile]?, Error?) -> Void) -> Void { Profile.getAll( completion) }
  • 85. struct Profile: Model { var name: String var photo: Data var dateOfBirth: Date } struct Query: QueryParams { var name: String } router.get("/profile", handler: getProfiles) func getProfiles(query: Query, completion: @escaping ([Profile]?, Error?) -> Void) -> Void { Profile.getAll(matching: query, completion) }