SlideShare a Scribd company logo
1 of 46
Download to read offline
Taking Swift to the Server
let me = Person(name: "Jens Ravens", company: "nerdgeschoss")
@JensRavens
GitHub: JensRavens
jensravens.com
nerdgeschoss.de
A short introduction to
http, tcp and ip.
Browser
http://jensravens.com
Browser
http://jensravens.com
DNS Server
Browser
http://jensravens.com
DNS Server
;; ANSWER SECTION:
jensravens.com. 3600 INA 37.120.178.83
Browser
http://jensravens.com
DNS Server
;; ANSWER SECTION:
jensravens.com. 3600 INA 37.120.178.83
37.120.178.83
Browser
http://jensravens.com
DNS Server
37.120.178.83
Browser
http://jensravens.com
DNS Server
37.120.178.83
GET / HTTP/1.1
Host: jensravens.com
User-Agent: curl/7.43.0
Accept: */*
Browser
http://jensravens.com
DNS Server
37.120.178.83
Server
GET / HTTP/1.1
Host: jensravens.com
User-Agent: curl/7.43.0
Accept: */*
Browser
http://jensravens.com
DNS Server
37.120.178.83
Server
Load Balancer
GET / HTTP/1.1
Host: jensravens.com
User-Agent: curl/7.43.0
Accept: */*
Browser
http://jensravens.com
DNS Server
37.120.178.83
Server
Load Balancer
App App
GET / HTTP/1.1
Host: jensravens.com
User-Agent: curl/7.43.0
Accept: */*
Browser
DNS Server Server
Load Balancer
App App
HTTP/1.1 200 OK
Content-Type: text/html
Content-Length: 7897
Connection: Keep-Alive
<!DOCTYPE html>
Browser
DNS Server Server
Load Balancer
App App
Hey, that’s just some
plain text over tcp!
Get a Request,
give a Response
public protocol RequestType {
var context: [String:AnyObject] { get set }
var method: HTTPMethod { get }
var path: String { get }
var params: [String:String] { get }
var headers: [String:String] { get }
var format: Format { get }
var body: Streamable? { get }
}
public protocol ResponseType {
var headers: [String: HeaderType] { get }
var code: StatusCode { get }
var content: Streamable { get }
}
public protocol RequestType {
var context: [String:AnyObject] { get set }
var method: HTTPMethod { get }
var path: String { get }
var params: [String:String] { get }
var headers: [String:String] { get }
var format: Format { get }
var body: Streamable? { get }
}
public protocol ResponseType {
var headers: [String: HeaderType] { get }
var code: StatusCode { get }
var content: Streamable { get }
}
public protocol RequestType {
var context: [String:AnyObject] { get set }
var method: HTTPMethod { get }
var path: String { get }
var params: [String:String] { get }
var headers: [String:String] { get }
var format: Format { get }
var body: Streamable? { get }
}
public protocol Streamable {
var stream: Void -> NSData? { get }
}
public typealias AppType = RequestType throws
-> ResponseType
public typealias AppType = RequestType throws
-> ResponseType
let myApp: AppType = { request in
return Response(code: 200, headers: [:],
content: "Hello World")
}
Where to go next:
The Router
public final class Router {
public func route(method: HTTPMethod, path: String,
app: Void -> AppType)
public func get(path: String, app: Void -> AppType)
public func app(request: RequestType) throws
-> ResponseType
}
public final class Router {
public func route(method: HTTPMethod, path: String,
app: Void -> AppType)
public func get(path: String, app: Void -> AppType)
public func app(request: RequestType) throws
-> ResponseType
}
let myApp: AppType = { request in
return Response(code: 200, headers: [:],
content: "Hello World")
}
public final class Router {
public func route(method: HTTPMethod, path: String,
app: Void -> AppType)
public func get(path: String, app: Void -> AppType)
public func app(request: RequestType) throws
-> ResponseType
}
let myApp: AppType = { request in
return Response(code: 200, headers: [:],
content: "Hello World")
}
let router = Router()
router.get("home") { myApp }
let routedApp = router.app
Making things pretty -
Rendering Views
public protocol ViewType {
func render() throws -> Streamable
var contentType: FormatType { get }
}
public protocol ViewType {
func render() throws -> Streamable
var contentType: FormatType { get }
}
public struct JSONView: ViewType {
public var contentType: FormatType { return Format.JSON }
let contents: AnyObject
public init(_ contents: AnyObject) {
self.contents = contents
}
public func render() throws -> Streamable {
return try NSJSONSerialization.dataWithJSONObject(
contents, options: .PrettyPrinted)
}
}
public protocol ControllerType {}
extension ControllerType {
func redirect(path: PathConvertible,
statusCode: StatusCode = 302) -> ResponseType
func render(view view: ViewType,
statusCode: StatusCode = 200) throws -> ResponseType
func render(json json: AnyObject,
statusCode: StatusCode = 200) throws -> ResponseType
func render(html html: String,
statusCode: StatusCode = 200) throws -> ResponseType
}
struct UsersController: ControllerType {
func index(request: RequestType) throws -> ResponseType {
let users: [User] = …
switch request.format {
case .JSON:
return try render(json: users.map { $0.json })
default:
return try render(view: MustacheView(name: "template",
context: users))
}
}
}
struct UsersController: ControllerType {
func index(request: RequestType) throws -> ResponseType {
let users: [User] = …
switch request.format {
case .JSON:
return try render(json: users.map { $0.json })
default:
return try render(view: MustacheView(name: "template",
context: users))
}
}
}
let router = Router()
router.get(“/users") { UsersController().index }
let routedApp = router.app
Extending the Stack -
Add some Middleware
public typealias MiddlewareType = AppType -> AppType
public func + (lhs: MiddlewareType, rhs: AppType) -> AppType {
return lhs(rhs)
}
public typealias MiddlewareType = AppType -> AppType
public func + (lhs: MiddlewareType, rhs: AppType) -> AppType {
return lhs(rhs)
}
let awesomeMiddleware: MiddlewareType = { app in
return { request in
var response = try app(request)
response.content = "Overwritten by middleware"
return response
}
}
public typealias MiddlewareType = AppType -> AppType
public func + (lhs: MiddlewareType, rhs: AppType) -> AppType {
return lhs(rhs)
}
let awesomeMiddleware: MiddlewareType = { app in
return { request in
var response = try app(request)
response.content = "Overwritten by middleware"
return response
}
}
let router = Router()
router.get(“/users")
{ awesomeMiddleware + UsersController().index }
let routedApp = router.app
class CookieStore {
struct Cookie {
public var name: String
public var value: String
public var validUntil: NSDate?
}
var cookies = [String:Cookie]()
subscript(key: String) -> String?
static func middleware(app: AppType) -> AppType
}
class CookieStore {
struct Cookie {
public var name: String
public var value: String
public var validUntil: NSDate?
}
var cookies = [String:Cookie]()
subscript(key: String) -> String?
static func middleware(app: AppType) -> AppType
}
let router = Router()
router.get(“/users")
{ CookieStore().middleware + UsersController().index }
let routedApp = router.app
class CookieStore {
struct Cookie {
public var name: String
public var value: String
public var validUntil: NSDate?
}
var cookies = [String:Cookie]()
subscript(key: String) -> String?
static func middleware(app: AppType) -> AppType
}
let router = Router()
router.get(“/users")
{ CookieStore().middleware + UsersController().index }
let routedApp = router.app
extension RequestType {
public var cookies: CookieStore!
}
func login(request: RequestType) throws -> ResponseType {
let secret = request.params["secret"] ?? ""
request.cookies["secret"] = secret
return try render(text: "Login successfull")
}
func secretStuff(request: RequestType) throws -> ResponseType {
if request.cookies["secret"] == "superSecret" {
return try render(text: "Here's the secret page")
} else {
return try render(text: "Permission denied!",
status: 403)
}
}
func login(request: RequestType) throws -> ResponseType {
let secret = request.params["secret"] ?? ""
request.cookies["secret"] = secret
return try render(text: "Login successfull")
}
func secretStuff(request: RequestType) throws -> ResponseType {
if request.cookies["secret"] == "superSecret" {
return try render(text: "Here's the secret page")
} else {
return try render(text: "Permission denied!",
status: 403)
}
}
let router = Router()
router.post(“/login”)
{ CookieStore().middleware + login }
router.get(“/my-secret-page“)
{ CookieStore().middleware + secretStuff }
let routedApp = router.app
Middleware
Cookies
Sessions
Current User
Format Detection
Custom Error Pages
HTTP Body Parser
Static File Server
Analytics
Mounting your App
Nest Server Interface
https://github.com/nestproject/Nest
import Curassow
import Inquiline
serve { request in
return Response(.Ok, contentType: "text/plain",
body: "Hello World")
}
Epoch
https://github.com/Zewo/Epoch
struct ServerResponder: ResponderType {
func respond(request: Request) -> Response {
// do something based on the Request
return Response(status: .OK)
}
}
let responder = ServerResponder()
let server = Server(port: 8080, responder: responder)
server.start()
Swag
https://github.com/swagproject/swag
import Foundation
import Curassow
import SwagNest
final class NextApp: App {
override init() {
super.init()
register(FileServer(root: publicDir).serve)
register(BodyParser.middleware)
register(CookieStore.middleware)
router.get(“/users") { UsersController.middleware +
UsersController().index }
router.get("/users/:id") { UsersController().show }
}
}
serve(NextApp().nest)
Thank you.
@JensRavens
github.com/swagproject/swag

More Related Content

What's hot

Parse cloud code
Parse cloud codeParse cloud code
Parse cloud code維佋 唐
 
第一次用Parse就深入淺出
第一次用Parse就深入淺出第一次用Parse就深入淺出
第一次用Parse就深入淺出Ymow Wu
 
&lt;x> Rails Web App Security Title
&lt;x> Rails Web App Security Title&lt;x> Rails Web App Security Title
&lt;x> Rails Web App Security Title'"><x> '"><x>
 
Working With Sharepoint 2013 Apps Development
Working With Sharepoint 2013 Apps DevelopmentWorking With Sharepoint 2013 Apps Development
Working With Sharepoint 2013 Apps DevelopmentPankaj Srivastava
 
Google cloud datastore driver for Google Apps Script DB abstraction
Google cloud datastore driver for Google Apps Script DB abstractionGoogle cloud datastore driver for Google Apps Script DB abstraction
Google cloud datastore driver for Google Apps Script DB abstractionBruce McPherson
 
 +  = ❤️ (Firebase for Apple Developers) at Swift Leeds
 +  = ❤️ (Firebase for Apple Developers) at Swift Leeds +  = ❤️ (Firebase for Apple Developers) at Swift Leeds
 +  = ❤️ (Firebase for Apple Developers) at Swift LeedsPeter Friese
 
Introduction to SharePoint 2013 REST API
Introduction to SharePoint 2013 REST APIIntroduction to SharePoint 2013 REST API
Introduction to SharePoint 2013 REST APIQUONTRASOLUTIONS
 
How To Manage API Request with AXIOS on a React Native App
How To Manage API Request with AXIOS on a React Native AppHow To Manage API Request with AXIOS on a React Native App
How To Manage API Request with AXIOS on a React Native AppAndolasoft Inc
 
Integrate CI/CD Pipelines with Jira Software Cloud
Integrate CI/CD Pipelines with Jira Software CloudIntegrate CI/CD Pipelines with Jira Software Cloud
Integrate CI/CD Pipelines with Jira Software CloudAtlassian
 
Lviv MDDay 2014. Ігор Коробка “забезпечення базової безпеки в андроїд аплікац...
Lviv MDDay 2014. Ігор Коробка “забезпечення базової безпеки в андроїд аплікац...Lviv MDDay 2014. Ігор Коробка “забезпечення базової безпеки в андроїд аплікац...
Lviv MDDay 2014. Ігор Коробка “забезпечення базової безпеки в андроїд аплікац...Lviv Startup Club
 
Firebase for Apple Developers
Firebase for Apple DevelopersFirebase for Apple Developers
Firebase for Apple DevelopersPeter Friese
 
Python Code Camp for Professionals 4/4
Python Code Camp for Professionals 4/4Python Code Camp for Professionals 4/4
Python Code Camp for Professionals 4/4DEVCON
 
Building Web Apps with the Esri-Leaflet Plugin - Dubai DevSummit 2013
Building Web Apps with the Esri-Leaflet Plugin - Dubai DevSummit 2013Building Web Apps with the Esri-Leaflet Plugin - Dubai DevSummit 2013
Building Web Apps with the Esri-Leaflet Plugin - Dubai DevSummit 2013Aaron Parecki
 
Python Code Camp for Professionals 3/4
Python Code Camp for Professionals 3/4Python Code Camp for Professionals 3/4
Python Code Camp for Professionals 3/4DEVCON
 

What's hot (20)

Intro to Parse
Intro to ParseIntro to Parse
Intro to Parse
 
What's Parse
What's ParseWhat's Parse
What's Parse
 
Parse cloud code
Parse cloud codeParse cloud code
Parse cloud code
 
第一次用Parse就深入淺出
第一次用Parse就深入淺出第一次用Parse就深入淺出
第一次用Parse就深入淺出
 
Parse Advanced
Parse AdvancedParse Advanced
Parse Advanced
 
&lt;x> Rails Web App Security Title
&lt;x> Rails Web App Security Title&lt;x> Rails Web App Security Title
&lt;x> Rails Web App Security Title
 
Android search
Android searchAndroid search
Android search
 
Working With Sharepoint 2013 Apps Development
Working With Sharepoint 2013 Apps DevelopmentWorking With Sharepoint 2013 Apps Development
Working With Sharepoint 2013 Apps Development
 
Google cloud datastore driver for Google Apps Script DB abstraction
Google cloud datastore driver for Google Apps Script DB abstractionGoogle cloud datastore driver for Google Apps Script DB abstraction
Google cloud datastore driver for Google Apps Script DB abstraction
 
 +  = ❤️ (Firebase for Apple Developers) at Swift Leeds
 +  = ❤️ (Firebase for Apple Developers) at Swift Leeds +  = ❤️ (Firebase for Apple Developers) at Swift Leeds
 +  = ❤️ (Firebase for Apple Developers) at Swift Leeds
 
Html indexed db
Html indexed dbHtml indexed db
Html indexed db
 
Introduction to SharePoint 2013 REST API
Introduction to SharePoint 2013 REST APIIntroduction to SharePoint 2013 REST API
Introduction to SharePoint 2013 REST API
 
How To Manage API Request with AXIOS on a React Native App
How To Manage API Request with AXIOS on a React Native AppHow To Manage API Request with AXIOS on a React Native App
How To Manage API Request with AXIOS on a React Native App
 
Integrate CI/CD Pipelines with Jira Software Cloud
Integrate CI/CD Pipelines with Jira Software CloudIntegrate CI/CD Pipelines with Jira Software Cloud
Integrate CI/CD Pipelines with Jira Software Cloud
 
Lviv MDDay 2014. Ігор Коробка “забезпечення базової безпеки в андроїд аплікац...
Lviv MDDay 2014. Ігор Коробка “забезпечення базової безпеки в андроїд аплікац...Lviv MDDay 2014. Ігор Коробка “забезпечення базової безпеки в андроїд аплікац...
Lviv MDDay 2014. Ігор Коробка “забезпечення базової безпеки в андроїд аплікац...
 
Url programming
Url programmingUrl programming
Url programming
 
Firebase for Apple Developers
Firebase for Apple DevelopersFirebase for Apple Developers
Firebase for Apple Developers
 
Python Code Camp for Professionals 4/4
Python Code Camp for Professionals 4/4Python Code Camp for Professionals 4/4
Python Code Camp for Professionals 4/4
 
Building Web Apps with the Esri-Leaflet Plugin - Dubai DevSummit 2013
Building Web Apps with the Esri-Leaflet Plugin - Dubai DevSummit 2013Building Web Apps with the Esri-Leaflet Plugin - Dubai DevSummit 2013
Building Web Apps with the Esri-Leaflet Plugin - Dubai DevSummit 2013
 
Python Code Camp for Professionals 3/4
Python Code Camp for Professionals 3/4Python Code Camp for Professionals 3/4
Python Code Camp for Professionals 3/4
 

Similar to Server Side Swift with Swag

Protocol-Oriented Networking
Protocol-Oriented NetworkingProtocol-Oriented Networking
Protocol-Oriented NetworkingMostafa Amer
 
Net/http and the http.handler interface
Net/http and the http.handler interfaceNet/http and the http.handler interface
Net/http and the http.handler interfaceJoakim Gustin
 
Net/http and the http.handler interface
Net/http and the http.handler interfaceNet/http and the http.handler interface
Net/http and the http.handler interfaceEvolve
 
Golang slidesaudrey
Golang slidesaudreyGolang slidesaudrey
Golang slidesaudreyAudrey Lim
 
服务框架: Thrift & PasteScript
服务框架: Thrift & PasteScript服务框架: Thrift & PasteScript
服务框架: Thrift & PasteScriptQiangning Hong
 
Local SQLite Database with Node for beginners
Local SQLite Database with Node for beginnersLocal SQLite Database with Node for beginners
Local SQLite Database with Node for beginnersLaurence Svekis ✔
 
Server Side Swift - AppBuilders 2017
Server Side Swift - AppBuilders 2017Server Side Swift - AppBuilders 2017
Server Side Swift - AppBuilders 2017Jens Ravens
 
Dart Power Tools
Dart Power ToolsDart Power Tools
Dart Power ToolsMatt Norris
 
What's New In Laravel 5
What's New In Laravel 5What's New In Laravel 5
What's New In Laravel 5Darren Craig
 
May 2010 - RestEasy
May 2010 - RestEasyMay 2010 - RestEasy
May 2010 - RestEasyJBug Italy
 
Using and scaling Rack and Rack-based middleware
Using and scaling Rack and Rack-based middlewareUsing and scaling Rack and Rack-based middleware
Using and scaling Rack and Rack-based middlewareAlona Mekhovova
 
Overview of RESTful web services
Overview of RESTful web servicesOverview of RESTful web services
Overview of RESTful web servicesnbuddharaju
 
Taming Core Data by Arek Holko, Macoscope
Taming Core Data by Arek Holko, MacoscopeTaming Core Data by Arek Holko, Macoscope
Taming Core Data by Arek Holko, MacoscopeMacoscope
 
Mashing up JavaScript – Advanced Techniques for modern Web Apps
Mashing up JavaScript – Advanced Techniques for modern Web AppsMashing up JavaScript – Advanced Techniques for modern Web Apps
Mashing up JavaScript – Advanced Techniques for modern Web AppsBastian Hofmann
 

Similar to Server Side Swift with Swag (20)

Android and REST
Android and RESTAndroid and REST
Android and REST
 
Protocol-Oriented Networking
Protocol-Oriented NetworkingProtocol-Oriented Networking
Protocol-Oriented Networking
 
Net/http and the http.handler interface
Net/http and the http.handler interfaceNet/http and the http.handler interface
Net/http and the http.handler interface
 
Net/http and the http.handler interface
Net/http and the http.handler interfaceNet/http and the http.handler interface
Net/http and the http.handler interface
 
Server Side Swift: Vapor
Server Side Swift: VaporServer Side Swift: Vapor
Server Side Swift: Vapor
 
Golang slidesaudrey
Golang slidesaudreyGolang slidesaudrey
Golang slidesaudrey
 
服务框架: Thrift & PasteScript
服务框架: Thrift & PasteScript服务框架: Thrift & PasteScript
服务框架: Thrift & PasteScript
 
Local SQLite Database with Node for beginners
Local SQLite Database with Node for beginnersLocal SQLite Database with Node for beginners
Local SQLite Database with Node for beginners
 
Server Side Swift - AppBuilders 2017
Server Side Swift - AppBuilders 2017Server Side Swift - AppBuilders 2017
Server Side Swift - AppBuilders 2017
 
Express JS
Express JSExpress JS
Express JS
 
Codemotion appengine
Codemotion appengineCodemotion appengine
Codemotion appengine
 
Dart Power Tools
Dart Power ToolsDart Power Tools
Dart Power Tools
 
What's New In Laravel 5
What's New In Laravel 5What's New In Laravel 5
What's New In Laravel 5
 
May 2010 - RestEasy
May 2010 - RestEasyMay 2010 - RestEasy
May 2010 - RestEasy
 
RESTEasy
RESTEasyRESTEasy
RESTEasy
 
Using and scaling Rack and Rack-based middleware
Using and scaling Rack and Rack-based middlewareUsing and scaling Rack and Rack-based middleware
Using and scaling Rack and Rack-based middleware
 
Overview of RESTful web services
Overview of RESTful web servicesOverview of RESTful web services
Overview of RESTful web services
 
Taming Core Data by Arek Holko, Macoscope
Taming Core Data by Arek Holko, MacoscopeTaming Core Data by Arek Holko, Macoscope
Taming Core Data by Arek Holko, Macoscope
 
RESTful web services
RESTful web servicesRESTful web services
RESTful web services
 
Mashing up JavaScript – Advanced Techniques for modern Web Apps
Mashing up JavaScript – Advanced Techniques for modern Web AppsMashing up JavaScript – Advanced Techniques for modern Web Apps
Mashing up JavaScript – Advanced Techniques for modern Web Apps
 

More from Jens Ravens

Turning it up to 11 - Scaling Ruby on Rails to 100k rps
Turning it up to 11 - Scaling Ruby on Rails to 100k rpsTurning it up to 11 - Scaling Ruby on Rails to 100k rps
Turning it up to 11 - Scaling Ruby on Rails to 100k rpsJens Ravens
 
Server Side Swift
Server Side SwiftServer Side Swift
Server Side SwiftJens Ravens
 
Working with Xcode and Swift Package Manager
Working with Xcode and Swift Package ManagerWorking with Xcode and Swift Package Manager
Working with Xcode and Swift Package ManagerJens Ravens
 
Taming Asynchronous Transforms with Interstellar
Taming Asynchronous Transforms with InterstellarTaming Asynchronous Transforms with Interstellar
Taming Asynchronous Transforms with InterstellarJens Ravens
 
Hipster oriented programming (Mobilization Lodz 2015)
Hipster oriented programming (Mobilization Lodz 2015)Hipster oriented programming (Mobilization Lodz 2015)
Hipster oriented programming (Mobilization Lodz 2015)Jens Ravens
 
Hipster Oriented Programming
Hipster Oriented ProgrammingHipster Oriented Programming
Hipster Oriented ProgrammingJens Ravens
 
Functional Reactive Programming without Black Magic (UIKonf 2015)
Functional Reactive Programming without Black Magic (UIKonf 2015)Functional Reactive Programming without Black Magic (UIKonf 2015)
Functional Reactive Programming without Black Magic (UIKonf 2015)Jens Ravens
 
Swift: Immutability and You
Swift: Immutability and YouSwift: Immutability and You
Swift: Immutability and YouJens Ravens
 

More from Jens Ravens (9)

Turning it up to 11 - Scaling Ruby on Rails to 100k rps
Turning it up to 11 - Scaling Ruby on Rails to 100k rpsTurning it up to 11 - Scaling Ruby on Rails to 100k rps
Turning it up to 11 - Scaling Ruby on Rails to 100k rps
 
Server Side Swift
Server Side SwiftServer Side Swift
Server Side Swift
 
Working with Xcode and Swift Package Manager
Working with Xcode and Swift Package ManagerWorking with Xcode and Swift Package Manager
Working with Xcode and Swift Package Manager
 
Taming Asynchronous Transforms with Interstellar
Taming Asynchronous Transforms with InterstellarTaming Asynchronous Transforms with Interstellar
Taming Asynchronous Transforms with Interstellar
 
Hipster oriented programming (Mobilization Lodz 2015)
Hipster oriented programming (Mobilization Lodz 2015)Hipster oriented programming (Mobilization Lodz 2015)
Hipster oriented programming (Mobilization Lodz 2015)
 
Hipster Oriented Programming
Hipster Oriented ProgrammingHipster Oriented Programming
Hipster Oriented Programming
 
Swift 2
Swift 2Swift 2
Swift 2
 
Functional Reactive Programming without Black Magic (UIKonf 2015)
Functional Reactive Programming without Black Magic (UIKonf 2015)Functional Reactive Programming without Black Magic (UIKonf 2015)
Functional Reactive Programming without Black Magic (UIKonf 2015)
 
Swift: Immutability and You
Swift: Immutability and YouSwift: Immutability and You
Swift: Immutability and You
 

Recently uploaded

Recruitment Management Software Benefits (Infographic)
Recruitment Management Software Benefits (Infographic)Recruitment Management Software Benefits (Infographic)
Recruitment Management Software Benefits (Infographic)Hr365.us smith
 
SpotFlow: Tracking Method Calls and States at Runtime
SpotFlow: Tracking Method Calls and States at RuntimeSpotFlow: Tracking Method Calls and States at Runtime
SpotFlow: Tracking Method Calls and States at Runtimeandrehoraa
 
How to Track Employee Performance A Comprehensive Guide.pdf
How to Track Employee Performance A Comprehensive Guide.pdfHow to Track Employee Performance A Comprehensive Guide.pdf
How to Track Employee Performance A Comprehensive Guide.pdfLivetecs LLC
 
Russian Call Girls in Karol Bagh Aasnvi ➡️ 8264348440 💋📞 Independent Escort S...
Russian Call Girls in Karol Bagh Aasnvi ➡️ 8264348440 💋📞 Independent Escort S...Russian Call Girls in Karol Bagh Aasnvi ➡️ 8264348440 💋📞 Independent Escort S...
Russian Call Girls in Karol Bagh Aasnvi ➡️ 8264348440 💋📞 Independent Escort S...soniya singh
 
Automate your Kamailio Test Calls - Kamailio World 2024
Automate your Kamailio Test Calls - Kamailio World 2024Automate your Kamailio Test Calls - Kamailio World 2024
Automate your Kamailio Test Calls - Kamailio World 2024Andreas Granig
 
Open Source Summit NA 2024: Open Source Cloud Costs - OpenCost's Impact on En...
Open Source Summit NA 2024: Open Source Cloud Costs - OpenCost's Impact on En...Open Source Summit NA 2024: Open Source Cloud Costs - OpenCost's Impact on En...
Open Source Summit NA 2024: Open Source Cloud Costs - OpenCost's Impact on En...Matt Ray
 
EY_Graph Database Powered Sustainability
EY_Graph Database Powered SustainabilityEY_Graph Database Powered Sustainability
EY_Graph Database Powered SustainabilityNeo4j
 
What are the key points to focus on before starting to learn ETL Development....
What are the key points to focus on before starting to learn ETL Development....What are the key points to focus on before starting to learn ETL Development....
What are the key points to focus on before starting to learn ETL Development....kzayra69
 
Introduction Computer Science - Software Design.pdf
Introduction Computer Science - Software Design.pdfIntroduction Computer Science - Software Design.pdf
Introduction Computer Science - Software Design.pdfFerryKemperman
 
Der Spagat zwischen BIAS und FAIRNESS (2024)
Der Spagat zwischen BIAS und FAIRNESS (2024)Der Spagat zwischen BIAS und FAIRNESS (2024)
Der Spagat zwischen BIAS und FAIRNESS (2024)OPEN KNOWLEDGE GmbH
 
Xen Safety Embedded OSS Summit April 2024 v4.pdf
Xen Safety Embedded OSS Summit April 2024 v4.pdfXen Safety Embedded OSS Summit April 2024 v4.pdf
Xen Safety Embedded OSS Summit April 2024 v4.pdfStefano Stabellini
 
ODSC - Batch to Stream workshop - integration of Apache Spark, Cassandra, Pos...
ODSC - Batch to Stream workshop - integration of Apache Spark, Cassandra, Pos...ODSC - Batch to Stream workshop - integration of Apache Spark, Cassandra, Pos...
ODSC - Batch to Stream workshop - integration of Apache Spark, Cassandra, Pos...Christina Lin
 
GOING AOT WITH GRAALVM – DEVOXX GREECE.pdf
GOING AOT WITH GRAALVM – DEVOXX GREECE.pdfGOING AOT WITH GRAALVM – DEVOXX GREECE.pdf
GOING AOT WITH GRAALVM – DEVOXX GREECE.pdfAlina Yurenko
 
Cloud Management Software Platforms: OpenStack
Cloud Management Software Platforms: OpenStackCloud Management Software Platforms: OpenStack
Cloud Management Software Platforms: OpenStackVICTOR MAESTRE RAMIREZ
 
Unveiling the Future: Sylius 2.0 New Features
Unveiling the Future: Sylius 2.0 New FeaturesUnveiling the Future: Sylius 2.0 New Features
Unveiling the Future: Sylius 2.0 New FeaturesŁukasz Chruściel
 
Alluxio Monthly Webinar | Cloud-Native Model Training on Distributed Data
Alluxio Monthly Webinar | Cloud-Native Model Training on Distributed DataAlluxio Monthly Webinar | Cloud-Native Model Training on Distributed Data
Alluxio Monthly Webinar | Cloud-Native Model Training on Distributed DataAlluxio, Inc.
 
Building a General PDE Solving Framework with Symbolic-Numeric Scientific Mac...
Building a General PDE Solving Framework with Symbolic-Numeric Scientific Mac...Building a General PDE Solving Framework with Symbolic-Numeric Scientific Mac...
Building a General PDE Solving Framework with Symbolic-Numeric Scientific Mac...stazi3110
 
办理学位证(UQ文凭证书)昆士兰大学毕业证成绩单原版一模一样
办理学位证(UQ文凭证书)昆士兰大学毕业证成绩单原版一模一样办理学位证(UQ文凭证书)昆士兰大学毕业证成绩单原版一模一样
办理学位证(UQ文凭证书)昆士兰大学毕业证成绩单原版一模一样umasea
 
Cloud Data Center Network Construction - IEEE
Cloud Data Center Network Construction - IEEECloud Data Center Network Construction - IEEE
Cloud Data Center Network Construction - IEEEVICTOR MAESTRE RAMIREZ
 
BATTLEFIELD ORM: TIPS, TACTICS AND STRATEGIES FOR CONQUERING YOUR DATABASE
BATTLEFIELD ORM: TIPS, TACTICS AND STRATEGIES FOR CONQUERING YOUR DATABASEBATTLEFIELD ORM: TIPS, TACTICS AND STRATEGIES FOR CONQUERING YOUR DATABASE
BATTLEFIELD ORM: TIPS, TACTICS AND STRATEGIES FOR CONQUERING YOUR DATABASEOrtus Solutions, Corp
 

Recently uploaded (20)

Recruitment Management Software Benefits (Infographic)
Recruitment Management Software Benefits (Infographic)Recruitment Management Software Benefits (Infographic)
Recruitment Management Software Benefits (Infographic)
 
SpotFlow: Tracking Method Calls and States at Runtime
SpotFlow: Tracking Method Calls and States at RuntimeSpotFlow: Tracking Method Calls and States at Runtime
SpotFlow: Tracking Method Calls and States at Runtime
 
How to Track Employee Performance A Comprehensive Guide.pdf
How to Track Employee Performance A Comprehensive Guide.pdfHow to Track Employee Performance A Comprehensive Guide.pdf
How to Track Employee Performance A Comprehensive Guide.pdf
 
Russian Call Girls in Karol Bagh Aasnvi ➡️ 8264348440 💋📞 Independent Escort S...
Russian Call Girls in Karol Bagh Aasnvi ➡️ 8264348440 💋📞 Independent Escort S...Russian Call Girls in Karol Bagh Aasnvi ➡️ 8264348440 💋📞 Independent Escort S...
Russian Call Girls in Karol Bagh Aasnvi ➡️ 8264348440 💋📞 Independent Escort S...
 
Automate your Kamailio Test Calls - Kamailio World 2024
Automate your Kamailio Test Calls - Kamailio World 2024Automate your Kamailio Test Calls - Kamailio World 2024
Automate your Kamailio Test Calls - Kamailio World 2024
 
Open Source Summit NA 2024: Open Source Cloud Costs - OpenCost's Impact on En...
Open Source Summit NA 2024: Open Source Cloud Costs - OpenCost's Impact on En...Open Source Summit NA 2024: Open Source Cloud Costs - OpenCost's Impact on En...
Open Source Summit NA 2024: Open Source Cloud Costs - OpenCost's Impact on En...
 
EY_Graph Database Powered Sustainability
EY_Graph Database Powered SustainabilityEY_Graph Database Powered Sustainability
EY_Graph Database Powered Sustainability
 
What are the key points to focus on before starting to learn ETL Development....
What are the key points to focus on before starting to learn ETL Development....What are the key points to focus on before starting to learn ETL Development....
What are the key points to focus on before starting to learn ETL Development....
 
Introduction Computer Science - Software Design.pdf
Introduction Computer Science - Software Design.pdfIntroduction Computer Science - Software Design.pdf
Introduction Computer Science - Software Design.pdf
 
Der Spagat zwischen BIAS und FAIRNESS (2024)
Der Spagat zwischen BIAS und FAIRNESS (2024)Der Spagat zwischen BIAS und FAIRNESS (2024)
Der Spagat zwischen BIAS und FAIRNESS (2024)
 
Xen Safety Embedded OSS Summit April 2024 v4.pdf
Xen Safety Embedded OSS Summit April 2024 v4.pdfXen Safety Embedded OSS Summit April 2024 v4.pdf
Xen Safety Embedded OSS Summit April 2024 v4.pdf
 
ODSC - Batch to Stream workshop - integration of Apache Spark, Cassandra, Pos...
ODSC - Batch to Stream workshop - integration of Apache Spark, Cassandra, Pos...ODSC - Batch to Stream workshop - integration of Apache Spark, Cassandra, Pos...
ODSC - Batch to Stream workshop - integration of Apache Spark, Cassandra, Pos...
 
GOING AOT WITH GRAALVM – DEVOXX GREECE.pdf
GOING AOT WITH GRAALVM – DEVOXX GREECE.pdfGOING AOT WITH GRAALVM – DEVOXX GREECE.pdf
GOING AOT WITH GRAALVM – DEVOXX GREECE.pdf
 
Cloud Management Software Platforms: OpenStack
Cloud Management Software Platforms: OpenStackCloud Management Software Platforms: OpenStack
Cloud Management Software Platforms: OpenStack
 
Unveiling the Future: Sylius 2.0 New Features
Unveiling the Future: Sylius 2.0 New FeaturesUnveiling the Future: Sylius 2.0 New Features
Unveiling the Future: Sylius 2.0 New Features
 
Alluxio Monthly Webinar | Cloud-Native Model Training on Distributed Data
Alluxio Monthly Webinar | Cloud-Native Model Training on Distributed DataAlluxio Monthly Webinar | Cloud-Native Model Training on Distributed Data
Alluxio Monthly Webinar | Cloud-Native Model Training on Distributed Data
 
Building a General PDE Solving Framework with Symbolic-Numeric Scientific Mac...
Building a General PDE Solving Framework with Symbolic-Numeric Scientific Mac...Building a General PDE Solving Framework with Symbolic-Numeric Scientific Mac...
Building a General PDE Solving Framework with Symbolic-Numeric Scientific Mac...
 
办理学位证(UQ文凭证书)昆士兰大学毕业证成绩单原版一模一样
办理学位证(UQ文凭证书)昆士兰大学毕业证成绩单原版一模一样办理学位证(UQ文凭证书)昆士兰大学毕业证成绩单原版一模一样
办理学位证(UQ文凭证书)昆士兰大学毕业证成绩单原版一模一样
 
Cloud Data Center Network Construction - IEEE
Cloud Data Center Network Construction - IEEECloud Data Center Network Construction - IEEE
Cloud Data Center Network Construction - IEEE
 
BATTLEFIELD ORM: TIPS, TACTICS AND STRATEGIES FOR CONQUERING YOUR DATABASE
BATTLEFIELD ORM: TIPS, TACTICS AND STRATEGIES FOR CONQUERING YOUR DATABASEBATTLEFIELD ORM: TIPS, TACTICS AND STRATEGIES FOR CONQUERING YOUR DATABASE
BATTLEFIELD ORM: TIPS, TACTICS AND STRATEGIES FOR CONQUERING YOUR DATABASE
 

Server Side Swift with Swag

  • 1. Taking Swift to the Server
  • 2. let me = Person(name: "Jens Ravens", company: "nerdgeschoss") @JensRavens GitHub: JensRavens jensravens.com nerdgeschoss.de
  • 3. A short introduction to http, tcp and ip.
  • 6. Browser http://jensravens.com DNS Server ;; ANSWER SECTION: jensravens.com. 3600 INA 37.120.178.83
  • 7. Browser http://jensravens.com DNS Server ;; ANSWER SECTION: jensravens.com. 3600 INA 37.120.178.83 37.120.178.83
  • 9. Browser http://jensravens.com DNS Server 37.120.178.83 GET / HTTP/1.1 Host: jensravens.com User-Agent: curl/7.43.0 Accept: */*
  • 10. Browser http://jensravens.com DNS Server 37.120.178.83 Server GET / HTTP/1.1 Host: jensravens.com User-Agent: curl/7.43.0 Accept: */*
  • 11. Browser http://jensravens.com DNS Server 37.120.178.83 Server Load Balancer GET / HTTP/1.1 Host: jensravens.com User-Agent: curl/7.43.0 Accept: */*
  • 12. Browser http://jensravens.com DNS Server 37.120.178.83 Server Load Balancer App App GET / HTTP/1.1 Host: jensravens.com User-Agent: curl/7.43.0 Accept: */*
  • 13. Browser DNS Server Server Load Balancer App App
  • 14. HTTP/1.1 200 OK Content-Type: text/html Content-Length: 7897 Connection: Keep-Alive <!DOCTYPE html> Browser DNS Server Server Load Balancer App App
  • 15. Hey, that’s just some plain text over tcp!
  • 16. Get a Request, give a Response
  • 17. public protocol RequestType { var context: [String:AnyObject] { get set } var method: HTTPMethod { get } var path: String { get } var params: [String:String] { get } var headers: [String:String] { get } var format: Format { get } var body: Streamable? { get } }
  • 18. public protocol ResponseType { var headers: [String: HeaderType] { get } var code: StatusCode { get } var content: Streamable { get } } public protocol RequestType { var context: [String:AnyObject] { get set } var method: HTTPMethod { get } var path: String { get } var params: [String:String] { get } var headers: [String:String] { get } var format: Format { get } var body: Streamable? { get } }
  • 19. public protocol ResponseType { var headers: [String: HeaderType] { get } var code: StatusCode { get } var content: Streamable { get } } public protocol RequestType { var context: [String:AnyObject] { get set } var method: HTTPMethod { get } var path: String { get } var params: [String:String] { get } var headers: [String:String] { get } var format: Format { get } var body: Streamable? { get } } public protocol Streamable { var stream: Void -> NSData? { get } }
  • 20. public typealias AppType = RequestType throws -> ResponseType
  • 21. public typealias AppType = RequestType throws -> ResponseType let myApp: AppType = { request in return Response(code: 200, headers: [:], content: "Hello World") }
  • 22. Where to go next: The Router
  • 23. public final class Router { public func route(method: HTTPMethod, path: String, app: Void -> AppType) public func get(path: String, app: Void -> AppType) public func app(request: RequestType) throws -> ResponseType }
  • 24. public final class Router { public func route(method: HTTPMethod, path: String, app: Void -> AppType) public func get(path: String, app: Void -> AppType) public func app(request: RequestType) throws -> ResponseType } let myApp: AppType = { request in return Response(code: 200, headers: [:], content: "Hello World") }
  • 25. public final class Router { public func route(method: HTTPMethod, path: String, app: Void -> AppType) public func get(path: String, app: Void -> AppType) public func app(request: RequestType) throws -> ResponseType } let myApp: AppType = { request in return Response(code: 200, headers: [:], content: "Hello World") } let router = Router() router.get("home") { myApp } let routedApp = router.app
  • 26. Making things pretty - Rendering Views
  • 27. public protocol ViewType { func render() throws -> Streamable var contentType: FormatType { get } }
  • 28. public protocol ViewType { func render() throws -> Streamable var contentType: FormatType { get } } public struct JSONView: ViewType { public var contentType: FormatType { return Format.JSON } let contents: AnyObject public init(_ contents: AnyObject) { self.contents = contents } public func render() throws -> Streamable { return try NSJSONSerialization.dataWithJSONObject( contents, options: .PrettyPrinted) } }
  • 29. public protocol ControllerType {} extension ControllerType { func redirect(path: PathConvertible, statusCode: StatusCode = 302) -> ResponseType func render(view view: ViewType, statusCode: StatusCode = 200) throws -> ResponseType func render(json json: AnyObject, statusCode: StatusCode = 200) throws -> ResponseType func render(html html: String, statusCode: StatusCode = 200) throws -> ResponseType }
  • 30. struct UsersController: ControllerType { func index(request: RequestType) throws -> ResponseType { let users: [User] = … switch request.format { case .JSON: return try render(json: users.map { $0.json }) default: return try render(view: MustacheView(name: "template", context: users)) } } }
  • 31. struct UsersController: ControllerType { func index(request: RequestType) throws -> ResponseType { let users: [User] = … switch request.format { case .JSON: return try render(json: users.map { $0.json }) default: return try render(view: MustacheView(name: "template", context: users)) } } } let router = Router() router.get(“/users") { UsersController().index } let routedApp = router.app
  • 32. Extending the Stack - Add some Middleware
  • 33. public typealias MiddlewareType = AppType -> AppType public func + (lhs: MiddlewareType, rhs: AppType) -> AppType { return lhs(rhs) }
  • 34. public typealias MiddlewareType = AppType -> AppType public func + (lhs: MiddlewareType, rhs: AppType) -> AppType { return lhs(rhs) } let awesomeMiddleware: MiddlewareType = { app in return { request in var response = try app(request) response.content = "Overwritten by middleware" return response } }
  • 35. public typealias MiddlewareType = AppType -> AppType public func + (lhs: MiddlewareType, rhs: AppType) -> AppType { return lhs(rhs) } let awesomeMiddleware: MiddlewareType = { app in return { request in var response = try app(request) response.content = "Overwritten by middleware" return response } } let router = Router() router.get(“/users") { awesomeMiddleware + UsersController().index } let routedApp = router.app
  • 36. class CookieStore { struct Cookie { public var name: String public var value: String public var validUntil: NSDate? } var cookies = [String:Cookie]() subscript(key: String) -> String? static func middleware(app: AppType) -> AppType }
  • 37. class CookieStore { struct Cookie { public var name: String public var value: String public var validUntil: NSDate? } var cookies = [String:Cookie]() subscript(key: String) -> String? static func middleware(app: AppType) -> AppType } let router = Router() router.get(“/users") { CookieStore().middleware + UsersController().index } let routedApp = router.app
  • 38. class CookieStore { struct Cookie { public var name: String public var value: String public var validUntil: NSDate? } var cookies = [String:Cookie]() subscript(key: String) -> String? static func middleware(app: AppType) -> AppType } let router = Router() router.get(“/users") { CookieStore().middleware + UsersController().index } let routedApp = router.app extension RequestType { public var cookies: CookieStore! }
  • 39. func login(request: RequestType) throws -> ResponseType { let secret = request.params["secret"] ?? "" request.cookies["secret"] = secret return try render(text: "Login successfull") } func secretStuff(request: RequestType) throws -> ResponseType { if request.cookies["secret"] == "superSecret" { return try render(text: "Here's the secret page") } else { return try render(text: "Permission denied!", status: 403) } }
  • 40. func login(request: RequestType) throws -> ResponseType { let secret = request.params["secret"] ?? "" request.cookies["secret"] = secret return try render(text: "Login successfull") } func secretStuff(request: RequestType) throws -> ResponseType { if request.cookies["secret"] == "superSecret" { return try render(text: "Here's the secret page") } else { return try render(text: "Permission denied!", status: 403) } } let router = Router() router.post(“/login”) { CookieStore().middleware + login } router.get(“/my-secret-page“) { CookieStore().middleware + secretStuff } let routedApp = router.app
  • 41. Middleware Cookies Sessions Current User Format Detection Custom Error Pages HTTP Body Parser Static File Server Analytics
  • 43. Nest Server Interface https://github.com/nestproject/Nest import Curassow import Inquiline serve { request in return Response(.Ok, contentType: "text/plain", body: "Hello World") }
  • 44. Epoch https://github.com/Zewo/Epoch struct ServerResponder: ResponderType { func respond(request: Request) -> Response { // do something based on the Request return Response(status: .OK) } } let responder = ServerResponder() let server = Server(port: 8080, responder: responder) server.start()
  • 45. Swag https://github.com/swagproject/swag import Foundation import Curassow import SwagNest final class NextApp: App { override init() { super.init() register(FileServer(root: publicDir).serve) register(BodyParser.middleware) register(CookieStore.middleware) router.get(“/users") { UsersController.middleware + UsersController().index } router.get("/users/:id") { UsersController().show } } } serve(NextApp().nest)