SlideShare a Scribd company logo
1 of 80
Download to read offline
 2016/09/10 H-LANE #hackt_h
HACKER TACKLE
Server Side? Swift
About Me
• 田中 孝明 (Takaaki Tanaka)
• クラスメソッド株式会社
• iOS アプリケーションエンジニア
• @kongmingtrap
• iOS Developer (Swift / Objective-C)
• GyazSquare / GitHub
Me and Fukuoka
ちょうど1年前まで住んでいました
Summary of Swift
Swift
Swift is a powerful and intuitive
programming language for macOS, iOS,
watchOS and tvOS. Writing Swift code is
interactive and fun, the syntax is concise
yet expressive, and Swift includes
modern features developers love. Swift
code is safe by design, yet also produces
software that runs lightning-fast.
History of Swift
• 0.x (2014/06)
• 1.0 (2014/09)
• 1.1 (2014/10)
• 1.2 (2015/02)
• 2.0 (2015/06)
• 2.1 (2015/10)
• 2.2 (2016/03)
• 3.0 (2016/09)
History of Swift
• 0.x (2014/06)
• 1.0 (2014/09)
• 1.1 (2014/10)
• 1.2 (2015/02)
• 2.0 (2015/06)
• 2.1 (2015/10)
• 2.2 (2016/03)
• 3.0 (2016/09)
黎明期
History of Swift
• 0.x (2014/06)
• 1.0 (2014/09)
• 1.1 (2014/10)
• 1.2 (2015/02)
• 2.0 (2015/06)
• 2.1 (2015/10)
• 2.2 (2016/03)
• 3.0 (2016/09)
成長期
History of Swift
• 0.x (2014/06)
• 1.0 (2014/09)
• 1.1 (2014/10)
• 1.2 (2015/02)
• 2.0 (2015/06)
• 2.1 (2015/10)
• 2.2 (2016/03)
• 3.0 (2016/09)
全盛期
[swift-evolution] Looking back on
Swift 3 and ahead to Swift 4
https://lists.swift.org/pipermail/swift-evolution/Week-of-Mon-20160725/025676.html
ABI安定化など、Swift 3.0で実装予定だっ
た機能が見送られ、Swift 4.0まで持ち越
される。。。
Swift is Open Source
https://developer.apple.com/swift/blog/?id=34
Going Server-side with Swift Open Source
https://developer.apple.com/videos/play/
wwdc2016/415/
WWDC2016
Architecture
https://developer.apple.com/videos/play/
wwdc2016/415/
Architecture
https://developer.apple.com/videos/play/
wwdc2016/415/
Agenda
• Server Side Swift frameworks
• Environment construct
• Make
• Deploy
Server Side Swift frameworks
https://github.com/PerfectlySoft/Perfect
Perfect
Perfect
• Swift における Rails の立ち位置を目指す
• 豊富なDB接続ライブラリ
• Mustacheテンプレート
• FastCGI + apache2 or Nginx
http://qutheory.io/
VAPOR
VAPOR
• Laraval like
• シンプルに記述できることを目指す
• ドキュメントが丁寧にまとめられている
https://github.com/vapor/vapor
https://developer.ibm.com/swift/kitura/
KITURA
KITURA
• IBM製
• IBMのクラウドプラットフォームBluemixがSwiftに対
応
• サンドボックスで試すことができる
• Swift関連の取り組みも熱心
https://github.com/IBM-Swift
http://www.zewo.io/
Zewo
Zewo
• 豊富なパッケージ数
• BaseComponentsをVaporと入れ替えることができ
る
https://github.com/Zewo
https://github.com/necolt/Swifton
Swifton
https://github.com/necolt/Swifton
Swifton
• Ruby on Rails like
https://github.com/noppoMan/Slimane
Slimane
https://github.com/noppoMan
Slimane
• expressにインスパイア
• マイクロフレームワーク+HTTPサーバー
• Yuki Takeiさん作成
Environment construct
今回のデモで採用
8000 star over.
Perfect Template
https://github.com/PerfectlySoft/PerfectTemplate.git
Build
Xcode 8.0 or later
OS X El Captan (10.11.6)
$ swift —version
Apple Swift version 3.0 (swiftlang-800.0.43.6 clang-800.0.38)
Target: x86_64-apple-macosx10.9
$ xcode-select --switch /Applications/Xcode.app/Contents/Developer
Build
$ brew install openssl
$ brew link openssl --force
Build
$ git clone https://github.com/PerfectlySoft/PerfectTemplate.git
$ cd PerfectTemplate
$ swift build
$ .build/debug/PerfectTemplate
// Create HTTP server.
let server = HTTPServer()
// Register your own routes and handlers
var routes = Routes()
// Add the routes to the server.
server.addRoutes(routes)
// Set a listen port of 8181
server.serverPort = 8181
// Set a document root.
// This is optional. If you do not want to serve static content then do not set this.
// Setting the document root will automatically add a static file handler for the route /**
server.documentRoot = "./webroot"
// Gather command line options and further configure the server.
// Run the server with --help to see the list of supported arguments.
// Command line arguments will supplant any of the values set above.
configureServer(server)
do {
// Launch the HTTP server.
try server.start()
} catch PerfectError.networkError(let err, let msg) {
print("Network error thrown: (err) (msg)")
}
Server Start
// Create HTTP server.
let server = HTTPServer()
// Register your own routes and handlers
var routes = Routes()
// Add the routes to the server.
server.addRoutes(routes)
// Set a listen port of 8181
server.serverPort = 8181
// Set a document root.
// This is optional. If you do not want to serve static content then do not set this.
// Setting the document root will automatically add a static file handler for the route /**
server.documentRoot = "./webroot"
// Gather command line options and further configure the server.
// Run the server with --help to see the list of supported arguments.
// Command line arguments will supplant any of the values set above.
configureServer(server)
do {
// Launch the HTTP server.
try server.start()
} catch PerfectError.networkError(let err, let msg) {
print("Network error thrown: (err) (msg)")
}
Server Start
// Create HTTP server.
let server = HTTPServer()
// Register your own routes and handlers
var routes = Routes()
// Add the routes to the server.
server.addRoutes(routes)
// Set a listen port of 8181
server.serverPort = 8181
// Set a document root.
// This is optional. If you do not want to serve static content then do not set this.
// Setting the document root will automatically add a static file handler for the route /**
server.documentRoot = "./webroot"
// Gather command line options and further configure the server.
// Run the server with --help to see the list of supported arguments.
// Command line arguments will supplant any of the values set above.
configureServer(server)
do {
// Launch the HTTP server.
try server.start()
} catch PerfectError.networkError(let err, let msg) {
print("Network error thrown: (err) (msg)")
}
Server Start
// Create HTTP server.
let server = HTTPServer()
// Register your own routes and handlers
var routes = Routes()
// Add the routes to the server.
server.addRoutes(routes)
// Set a listen port of 8181
server.serverPort = 8181
// Set a document root.
// This is optional. If you do not want to serve static content then do not set this.
// Setting the document root will automatically add a static file handler for the route /**
server.documentRoot = "./webroot"
// Gather command line options and further configure the server.
// Run the server with --help to see the list of supported arguments.
// Command line arguments will supplant any of the values set above.
configureServer(server)
do {
// Launch the HTTP server.
try server.start()
} catch PerfectError.networkError(let err, let msg) {
print("Network error thrown: (err) (msg)")
}
Server Start
// Create HTTP server.
let server = HTTPServer()
// Register your own routes and handlers
var routes = Routes()
// Add the routes to the server.
server.addRoutes(routes)
// Set a listen port of 8181
server.serverPort = 8181
// Set a document root.
// This is optional. If you do not want to serve static content then do not set this.
// Setting the document root will automatically add a static file handler for the route /**
server.documentRoot = "./webroot"
// Gather command line options and further configure the server.
// Run the server with --help to see the list of supported arguments.
// Command line arguments will supplant any of the values set above.
configureServer(server)
do {
// Launch the HTTP server.
try server.start()
} catch PerfectError.networkError(let err, let msg) {
print("Network error thrown: (err) (msg)")
}
Server Start
Make
Router
// list
routes.add(method: .get, uri: "/list", handler: listHandler)
// login
routes.add(method: .post, uri: "/login", handler: loginHandler)
// get message
routes.add(method: .get, uri: "/message", handler: getMessageHandler)
// post message
routes.add(method: .post, uri: "/message", handler: postMessageHandler)
https://github.com/PerfectlySoft/PerfectExample-
URLRouting
GET Method
// listHandler
func listHandler(request: HTTPRequest, _ response: HTTPResponse) {
defer {
response.completed()
}
response.setHeader(.contentType, value: "application/json")
do {
let listArray: [String : Any] = [
"name1": 300,
"name2": 230.45,
"name3": 150
]
try response.setBody(json: listArray)
} catch let error as NSError {
print(error)
}
}
GET Method
curl -v -H "Accept: application/json" -H "Content-type: application/json" -
X GET http://0.0.0.0:8181/list
* Trying 0.0.0.0...
* Connected to 0.0.0.0 (127.0.0.1) port 8181 (#0)
> GET /list HTTP/1.1
> Host: 0.0.0.0:8181
> User-Agent: curl/7.43.0
> Accept: application/json
> Content-type: application/json
>
< HTTP/1.1 200 OK
< Content-Type: application/json
< Connection: Keep-Alive
< Content-Length: 40
<
* Connection #0 to host 0.0.0.0 left intact
{"name1":300,"name2":230.45,"name3":150}
GET Method
// check thread
let thread = Thread.current
print(thread)
[INFO] Starting HTTP server on 0.0.0.0:8181 with document root ./webroot
<NSThread: 0x7fab61c15530>{number = 2, name = (null)}
<NSThread: 0x7fab61e06cd0>{number = 3, name = (null)}
<NSThread: 0x7fab61f05290>{number = 4, name = (null)}
全てのリクエストが別のThreadで実行さ
れていることがわかる
POST Method
// loginHandler
func loginHandler(request: HTTPRequest, _ response: HTTPResponse) {
defer {
response.completed()
}
do {
let json = try request.postBodyString?.jsonDecode()
response.setHeader(.contentType, value: "application/json")
guard let decoded = json as? [String : Any] else { return }
let result: [String : Any] = decoded["user"].map {
["result": true, "user": $0]
} ?? ["result": false]
try response.setBody(json: result)
} catch let error as NSError {
print(error)
}
}
POST Method
curl -v -H "Accept: application/json" -H "Content-type: application/json" -
X POST -d '{"user": "tana"}' http://0.0.0.0:8181/login
* Trying 0.0.0.0...
* Connected to 0.0.0.0 (127.0.0.1) port 8181 (#0)
> POST /login HTTP/1.1
> Host: 0.0.0.0:8181
> User-Agent: curl/7.43.0
> Accept: application/json
> Content-type: application/json
> Content-Length: 16
>
* upload completely sent off: 16 out of 16 bytes
< HTTP/1.1 200 OK
< Content-Type: application/json
< Connection: Keep-Alive
< Content-Length: 29
<
* Connection #0 to host 0.0.0.0 left intact
{"result":true,"user":"tana"}
Database
• Perfect Redis
• Perfect SQLite
• Perfect PostgreSQL
• Perfect MySQL
• Perfect MongoDB
• Perfect FileMaker
DB Connector
• Perfect Redis
• Perfect SQLite
• Perfect PostgreSQL
• Perfect MySQL
• Perfect MongoDB
• Perfect FileMaker
DB Connector
https://github.com/PerfectlySoft/Perfect-PostgreSQL
let package = Package(
name: "PerfectTemplate",
targets: [],
dependencies: [
.Package(
url: "https://github.com/PerfectlySoft/
Perfect-PostgreSQL.git",
versions: Version(0,0,0)..<Version(10,0,0))
]
)
Postgresql
プロジェクト直下のpackage.swiftに
Perfect-PostgresSQLを追加する
create table message (
id serial primary key,
message text,
created_at timestamp with time zone,
updated_at timestamp with time zone
);
• create message table
Create Table
GET Method
// get message
routes.add(method: .get, uri: "/message", handler: {
request, response in
defer {
response.completed()
}
do {
response.setHeader(.contentType, value: "application/json")
let connection = PGConnection()
let status = connection.connectdb(db)
let result = connection.exec(
statement: "select * FROM message order by updated_at desc")
…
// DB
let db = "postgresql://samplefuku:fukuoka@localhost:5432/exampledb"
GET Method…
let num = result.numTuples()
let messages: [[String : Any]] = (0..<num).map { x in
let t1 = result.getFieldString(tupleIndex: x, fieldIndex: 0)
let t2 = result.getFieldString(tupleIndex: x, fieldIndex: 1)
let t3 = result.getFieldString(tupleIndex: x, fieldIndex: 2)
let t4 = result.getFieldString(tupleIndex: x, fieldIndex: 3)
let message: [String : Any] = [
"id" : t1,
"message" : t2,
"created_at" : t3,
"updated_at" : t4
]
return message
}
result.clear()
connection.close()
try response.setBody(json: ["messages" : messages])
} catch let error as NSError {
print(error)
}
})
POST Method
// post message
routes.add(method: .post, uri: "/message", handler: {
request, response in
defer {
response.completed()
}
do {
let json = try request.postBodyString?.jsonDecode()
response.setHeader(.contentType, value: “application/json")
guard let decoded = json as? [String : Any] else { return }
…
POST Method
…
let result: [String : Any] = decoded["message"].map { message in
let connection = PGConnection()
let status = connection.connectdb(db)
let date = Date()
let createdAt = RFC3339DateFormatter.string(from: date)
let updatedAt = RFC3339DateFormatter.string(from: date)
let result = connection.exec(
statement: "insert into message (message, created_at,
updated_at) values($1, $2, $3)",
params: ["(message)", "(createdAt)", "(updatedAt)"])
result.clear()
connection.close()
return ["message" : message]
} ?? [:]
try response.setBody(json: result)
…
Demo
Deploy
http://perfect.org/heroku-buildpack-for-perfect-and-
swift.html
Heroku Buildpack for Perfect
and Swift
http://perfect.org/aws-buildpack-for-perfect-and-
swift.html
AWS Buildpack for Perfect and
Swift
AMI
AWSのマネージメントコンソールにログインし、
EC2のAMIから「us-east-1」リージョンにある
パブリックイメージから「perfect-ubuntu-1510」を
検索します。
AMI
セキュリティグループのインバウンドにHTTPを
追加しておく
AMI
$ sudo ssh -i ~/.ssh/xxxxx.pem ubuntu@xx.xxx.xx.xxx
AMI
$ wget https://swift.org/builds/development/ubuntu1510/swift-DEVELOPMENT-
SNAPSHOT-2016-08-26-a/swift-DEVELOPMENT-SNAPSHOT-2016-08-26-a-ubuntu15.10.tar.gz
$ tar xzf swift-DEVELOPMENT-SNAPSHOT-2016-08-26-a-ubuntu15.10.tar.gz
https://swift.org/download/#using-downloads
AMIにインストールされているのがSwift 2.2のため、
ビルドするためにサポートされているSwift 3.0の
SNAPSHOTを取得する
$ export PATH=./swift-DEVELOPMENT-SNAPSHOT-2016-08-26-a-ubuntu15.10/usr/bin:"$
{PATH}"
Build & Run
$ cd PerfectTemplate
$ swift build
$ .build/debug/PerfectTemplate
Demo
Appendix
Call Shell
// Commandline
func command(launchPath: String, arguments: [String]) -> String {
let task = Process()
task.launchPath = launchPath
task.arguments = arguments
let pipe = Pipe()
task.standardOutput = pipe
task.launch()
let data = pipe.fileHandleForReading.readDataToEndOfFile()
let output = String(
data: data,
encoding: String.Encoding.utf8)!
return output
}
let cl = command(launchPath: "/bin/echo", arguments: ["aaaa"])
Recap
• 絶賛発展途上
• クライアントサイドの開発者もWebAPI
の開発を経験しやすくなった
• コミッターになりやすい
Recap
Happy Swift life!!
One more thing...
http://dev.classmethod.jp/news/
developers-io-2016-in-fukuoka/
http://dev.classmethod.jp/news/job-
fair-20161007/
ありがとうございました🙇

More Related Content

What's hot

Deploy Rails Application by Capistrano
Deploy Rails Application by CapistranoDeploy Rails Application by Capistrano
Deploy Rails Application by CapistranoTasawr Interactive
 
Puppet Camp Phoenix 2015: Managing Files via Puppet: Let Me Count The Ways (B...
Puppet Camp Phoenix 2015: Managing Files via Puppet: Let Me Count The Ways (B...Puppet Camp Phoenix 2015: Managing Files via Puppet: Let Me Count The Ways (B...
Puppet Camp Phoenix 2015: Managing Files via Puppet: Let Me Count The Ways (B...Puppet
 
Ansible - Swiss Army Knife Orchestration
Ansible - Swiss Army Knife OrchestrationAnsible - Swiss Army Knife Orchestration
Ansible - Swiss Army Knife Orchestrationbcoca
 
Failsafe Mechanism for Yahoo Homepage
Failsafe Mechanism for Yahoo HomepageFailsafe Mechanism for Yahoo Homepage
Failsafe Mechanism for Yahoo HomepageKit Chan
 
Aura Project for PHP
Aura Project for PHPAura Project for PHP
Aura Project for PHPHari K T
 
Replacing Squid with ATS
Replacing Squid with ATSReplacing Squid with ATS
Replacing Squid with ATSKit Chan
 
Ansible leveraging 2.0
Ansible leveraging 2.0Ansible leveraging 2.0
Ansible leveraging 2.0bcoca
 
Oliver hookins puppetcamp2011
Oliver hookins puppetcamp2011Oliver hookins puppetcamp2011
Oliver hookins puppetcamp2011Puppet
 
Getting Started with Ansible
Getting Started with AnsibleGetting Started with Ansible
Getting Started with Ansibleahamilton55
 
Introduction to ansible
Introduction to ansibleIntroduction to ansible
Introduction to ansibleOmid Vahdaty
 
Configuration management II - Terraform
Configuration management II - TerraformConfiguration management II - Terraform
Configuration management II - TerraformXavier Serrat Bordas
 
Apache FTP Server Integration
Apache FTP Server IntegrationApache FTP Server Integration
Apache FTP Server IntegrationWO Community
 
MySQL Monitoring using Prometheus & Grafana
MySQL Monitoring using Prometheus & GrafanaMySQL Monitoring using Prometheus & Grafana
MySQL Monitoring using Prometheus & GrafanaYoungHeon (Roy) Kim
 
Ansible loves Python, Python Philadelphia meetup
Ansible loves Python, Python Philadelphia meetupAnsible loves Python, Python Philadelphia meetup
Ansible loves Python, Python Philadelphia meetupGreg DeKoenigsberg
 
Exploring Async PHP (SF Live Berlin 2019)
Exploring Async PHP (SF Live Berlin 2019)Exploring Async PHP (SF Live Berlin 2019)
Exploring Async PHP (SF Live Berlin 2019)dantleech
 
#OktoCampus - Workshop : An introduction to Ansible
#OktoCampus - Workshop : An introduction to Ansible#OktoCampus - Workshop : An introduction to Ansible
#OktoCampus - Workshop : An introduction to AnsibleCédric Delgehier
 
Vagrant for real (codemotion rome 2016)
Vagrant for real (codemotion rome 2016)Vagrant for real (codemotion rome 2016)
Vagrant for real (codemotion rome 2016)Michele Orselli
 
2005_Structures and functions of Makefile
2005_Structures and functions of Makefile2005_Structures and functions of Makefile
2005_Structures and functions of MakefileNakCheon Jung
 

What's hot (20)

Deploy Rails Application by Capistrano
Deploy Rails Application by CapistranoDeploy Rails Application by Capistrano
Deploy Rails Application by Capistrano
 
Puppet Camp Phoenix 2015: Managing Files via Puppet: Let Me Count The Ways (B...
Puppet Camp Phoenix 2015: Managing Files via Puppet: Let Me Count The Ways (B...Puppet Camp Phoenix 2015: Managing Files via Puppet: Let Me Count The Ways (B...
Puppet Camp Phoenix 2015: Managing Files via Puppet: Let Me Count The Ways (B...
 
Ansible - Swiss Army Knife Orchestration
Ansible - Swiss Army Knife OrchestrationAnsible - Swiss Army Knife Orchestration
Ansible - Swiss Army Knife Orchestration
 
Failsafe Mechanism for Yahoo Homepage
Failsafe Mechanism for Yahoo HomepageFailsafe Mechanism for Yahoo Homepage
Failsafe Mechanism for Yahoo Homepage
 
Aura Project for PHP
Aura Project for PHPAura Project for PHP
Aura Project for PHP
 
Replacing Squid with ATS
Replacing Squid with ATSReplacing Squid with ATS
Replacing Squid with ATS
 
Ansible leveraging 2.0
Ansible leveraging 2.0Ansible leveraging 2.0
Ansible leveraging 2.0
 
Refactoring terraform
Refactoring terraformRefactoring terraform
Refactoring terraform
 
Oliver hookins puppetcamp2011
Oliver hookins puppetcamp2011Oliver hookins puppetcamp2011
Oliver hookins puppetcamp2011
 
Getting Started with Ansible
Getting Started with AnsibleGetting Started with Ansible
Getting Started with Ansible
 
Introduction to ansible
Introduction to ansibleIntroduction to ansible
Introduction to ansible
 
Configuration management II - Terraform
Configuration management II - TerraformConfiguration management II - Terraform
Configuration management II - Terraform
 
Apache FTP Server Integration
Apache FTP Server IntegrationApache FTP Server Integration
Apache FTP Server Integration
 
MySQL Monitoring using Prometheus & Grafana
MySQL Monitoring using Prometheus & GrafanaMySQL Monitoring using Prometheus & Grafana
MySQL Monitoring using Prometheus & Grafana
 
Ansible loves Python, Python Philadelphia meetup
Ansible loves Python, Python Philadelphia meetupAnsible loves Python, Python Philadelphia meetup
Ansible loves Python, Python Philadelphia meetup
 
Exploring Async PHP (SF Live Berlin 2019)
Exploring Async PHP (SF Live Berlin 2019)Exploring Async PHP (SF Live Berlin 2019)
Exploring Async PHP (SF Live Berlin 2019)
 
Generators
GeneratorsGenerators
Generators
 
#OktoCampus - Workshop : An introduction to Ansible
#OktoCampus - Workshop : An introduction to Ansible#OktoCampus - Workshop : An introduction to Ansible
#OktoCampus - Workshop : An introduction to Ansible
 
Vagrant for real (codemotion rome 2016)
Vagrant for real (codemotion rome 2016)Vagrant for real (codemotion rome 2016)
Vagrant for real (codemotion rome 2016)
 
2005_Structures and functions of Makefile
2005_Structures and functions of Makefile2005_Structures and functions of Makefile
2005_Structures and functions of Makefile
 

Viewers also liked

Enumはデキる子 ~ case .Success(let value): ~
 Enumはデキる子 ~ case .Success(let value): ~ Enumはデキる子 ~ case .Success(let value): ~
Enumはデキる子 ~ case .Success(let value): ~Takaaki Tanaka
 
An introduction to Microservices
An introduction to MicroservicesAn introduction to Microservices
An introduction to MicroservicesCisco DevNet
 
An Introduction to OAuth 2
An Introduction to OAuth 2An Introduction to OAuth 2
An Introduction to OAuth 2Aaron Parecki
 
Server-side Swift
Server-side SwiftServer-side Swift
Server-side SwiftDaijiro Abe
 
Authentication: Cookies vs JWTs and why you’re doing it wrong
Authentication: Cookies vs JWTs and why you’re doing it wrongAuthentication: Cookies vs JWTs and why you’re doing it wrong
Authentication: Cookies vs JWTs and why you’re doing it wrongDerek Perkins
 

Viewers also liked (7)

Server Side Swift
Server Side SwiftServer Side Swift
Server Side Swift
 
Enumはデキる子 ~ case .Success(let value): ~
 Enumはデキる子 ~ case .Success(let value): ~ Enumはデキる子 ~ case .Success(let value): ~
Enumはデキる子 ~ case .Success(let value): ~
 
Server-side Swift
Server-side SwiftServer-side Swift
Server-side Swift
 
An introduction to Microservices
An introduction to MicroservicesAn introduction to Microservices
An introduction to Microservices
 
An Introduction to OAuth 2
An Introduction to OAuth 2An Introduction to OAuth 2
An Introduction to OAuth 2
 
Server-side Swift
Server-side SwiftServer-side Swift
Server-side Swift
 
Authentication: Cookies vs JWTs and why you’re doing it wrong
Authentication: Cookies vs JWTs and why you’re doing it wrongAuthentication: Cookies vs JWTs and why you’re doing it wrong
Authentication: Cookies vs JWTs and why you’re doing it wrong
 

Similar to Server Side? Swift

Node.js System: The Approach
Node.js System: The ApproachNode.js System: The Approach
Node.js System: The ApproachHaci Murat Yaman
 
nodejs_at_a_glance.ppt
nodejs_at_a_glance.pptnodejs_at_a_glance.ppt
nodejs_at_a_glance.pptWalaSidhom1
 
16network Programming Servers
16network Programming Servers16network Programming Servers
16network Programming ServersAdil Jafri
 
Iss letcure 7_8
Iss letcure 7_8Iss letcure 7_8
Iss letcure 7_8Ali Habeeb
 
Sharding and Load Balancing in Scala - Twitter's Finagle
Sharding and Load Balancing in Scala - Twitter's FinagleSharding and Load Balancing in Scala - Twitter's Finagle
Sharding and Load Balancing in Scala - Twitter's FinagleGeoff Ballinger
 
692015 programming assignment 1 building a multi­threaded w
692015 programming assignment 1 building a multi­threaded w692015 programming assignment 1 building a multi­threaded w
692015 programming assignment 1 building a multi­threaded wsmile790243
 
Writing robust Node.js applications
Writing robust Node.js applicationsWriting robust Node.js applications
Writing robust Node.js applicationsTom Croucher
 
Service Discovery using etcd, Consul and Kubernetes
Service Discovery using etcd, Consul and KubernetesService Discovery using etcd, Consul and Kubernetes
Service Discovery using etcd, Consul and KubernetesSreenivas Makam
 
Web container and Apache Tomcat
Web container and Apache TomcatWeb container and Apache Tomcat
Web container and Apache TomcatAuwal Amshi
 
Html servlet example
Html   servlet exampleHtml   servlet example
Html servlet examplervpprash
 

Similar to Server Side? Swift (20)

Node.js System: The Approach
Node.js System: The ApproachNode.js System: The Approach
Node.js System: The Approach
 
nodejs_at_a_glance.ppt
nodejs_at_a_glance.pptnodejs_at_a_glance.ppt
nodejs_at_a_glance.ppt
 
16network Programming Servers
16network Programming Servers16network Programming Servers
16network Programming Servers
 
Iss letcure 7_8
Iss letcure 7_8Iss letcure 7_8
Iss letcure 7_8
 
Web
WebWeb
Web
 
Sharding and Load Balancing in Scala - Twitter's Finagle
Sharding and Load Balancing in Scala - Twitter's FinagleSharding and Load Balancing in Scala - Twitter's Finagle
Sharding and Load Balancing in Scala - Twitter's Finagle
 
Apache
ApacheApache
Apache
 
692015 programming assignment 1 building a multi­threaded w
692015 programming assignment 1 building a multi­threaded w692015 programming assignment 1 building a multi­threaded w
692015 programming assignment 1 building a multi­threaded w
 
Writing robust Node.js applications
Writing robust Node.js applicationsWriting robust Node.js applications
Writing robust Node.js applications
 
Service Discovery using etcd, Consul and Kubernetes
Service Discovery using etcd, Consul and KubernetesService Discovery using etcd, Consul and Kubernetes
Service Discovery using etcd, Consul and Kubernetes
 
Express node js
Express node jsExpress node js
Express node js
 
Hack ASP.NET website
Hack ASP.NET websiteHack ASP.NET website
Hack ASP.NET website
 
Java Servlets
Java ServletsJava Servlets
Java Servlets
 
TO Hack an ASP .NET website?
TO Hack an ASP .NET website?  TO Hack an ASP .NET website?
TO Hack an ASP .NET website?
 
Web container and Apache Tomcat
Web container and Apache TomcatWeb container and Apache Tomcat
Web container and Apache Tomcat
 
Play!ng with scala
Play!ng with scalaPlay!ng with scala
Play!ng with scala
 
Apache Ppt
Apache PptApache Ppt
Apache Ppt
 
Apache ppt
Apache pptApache ppt
Apache ppt
 
Html servlet example
Html   servlet exampleHtml   servlet example
Html servlet example
 
Apache
ApacheApache
Apache
 

More from Takaaki Tanaka

Swiftをキめると 気持ちいい!
Swiftをキめると 気持ちいい!Swiftをキめると 気持ちいい!
Swiftをキめると 気持ちいい!Takaaki Tanaka
 
AndroidーiOS開発比較〜iOSエンジニアから見たAndroidのアレコレ〜
AndroidーiOS開発比較〜iOSエンジニアから見たAndroidのアレコレ〜AndroidーiOS開発比較〜iOSエンジニアから見たAndroidのアレコレ〜
AndroidーiOS開発比較〜iOSエンジニアから見たAndroidのアレコレ〜Takaaki Tanaka
 
全部見せます!最前線エンジニアが語るBleアプリケーションのハマりどころ(i os)
全部見せます!最前線エンジニアが語るBleアプリケーションのハマりどころ(i os)全部見せます!最前線エンジニアが語るBleアプリケーションのハマりどころ(i os)
全部見せます!最前線エンジニアが語るBleアプリケーションのハマりどころ(i os)Takaaki Tanaka
 
Swift api design guidelines (dec 3, 2015)
Swift api design guidelines (dec 3, 2015)Swift api design guidelines (dec 3, 2015)
Swift api design guidelines (dec 3, 2015)Takaaki Tanaka
 
モバイル開発者から見た サーバーレスアーキテクチャ
モバイル開発者から見た サーバーレスアーキテクチャモバイル開発者から見た サーバーレスアーキテクチャ
モバイル開発者から見た サーバーレスアーキテクチャTakaaki Tanaka
 
AddressBook to Contacts
AddressBook to ContactsAddressBook to Contacts
AddressBook to ContactsTakaaki Tanaka
 

More from Takaaki Tanaka (6)

Swiftをキめると 気持ちいい!
Swiftをキめると 気持ちいい!Swiftをキめると 気持ちいい!
Swiftをキめると 気持ちいい!
 
AndroidーiOS開発比較〜iOSエンジニアから見たAndroidのアレコレ〜
AndroidーiOS開発比較〜iOSエンジニアから見たAndroidのアレコレ〜AndroidーiOS開発比較〜iOSエンジニアから見たAndroidのアレコレ〜
AndroidーiOS開発比較〜iOSエンジニアから見たAndroidのアレコレ〜
 
全部見せます!最前線エンジニアが語るBleアプリケーションのハマりどころ(i os)
全部見せます!最前線エンジニアが語るBleアプリケーションのハマりどころ(i os)全部見せます!最前線エンジニアが語るBleアプリケーションのハマりどころ(i os)
全部見せます!最前線エンジニアが語るBleアプリケーションのハマりどころ(i os)
 
Swift api design guidelines (dec 3, 2015)
Swift api design guidelines (dec 3, 2015)Swift api design guidelines (dec 3, 2015)
Swift api design guidelines (dec 3, 2015)
 
モバイル開発者から見た サーバーレスアーキテクチャ
モバイル開発者から見た サーバーレスアーキテクチャモバイル開発者から見た サーバーレスアーキテクチャ
モバイル開発者から見た サーバーレスアーキテクチャ
 
AddressBook to Contacts
AddressBook to ContactsAddressBook to Contacts
AddressBook to Contacts
 

Recently uploaded

GenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day PresentationGenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day PresentationMichael W. Hawkins
 
Tech-Forward - Achieving Business Readiness For Copilot in Microsoft 365
Tech-Forward - Achieving Business Readiness For Copilot in Microsoft 365Tech-Forward - Achieving Business Readiness For Copilot in Microsoft 365
Tech-Forward - Achieving Business Readiness For Copilot in Microsoft 3652toLead Limited
 
Unblocking The Main Thread Solving ANRs and Frozen Frames
Unblocking The Main Thread Solving ANRs and Frozen FramesUnblocking The Main Thread Solving ANRs and Frozen Frames
Unblocking The Main Thread Solving ANRs and Frozen FramesSinan KOZAK
 
Handwritten Text Recognition for manuscripts and early printed texts
Handwritten Text Recognition for manuscripts and early printed textsHandwritten Text Recognition for manuscripts and early printed texts
Handwritten Text Recognition for manuscripts and early printed textsMaria Levchenko
 
Histor y of HAM Radio presentation slide
Histor y of HAM Radio presentation slideHistor y of HAM Radio presentation slide
Histor y of HAM Radio presentation slidevu2urc
 
08448380779 Call Girls In Civil Lines Women Seeking Men
08448380779 Call Girls In Civil Lines Women Seeking Men08448380779 Call Girls In Civil Lines Women Seeking Men
08448380779 Call Girls In Civil Lines Women Seeking MenDelhi Call girls
 
Breaking the Kubernetes Kill Chain: Host Path Mount
Breaking the Kubernetes Kill Chain: Host Path MountBreaking the Kubernetes Kill Chain: Host Path Mount
Breaking the Kubernetes Kill Chain: Host Path MountPuma Security, LLC
 
Data Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt RobisonData Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt RobisonAnna Loughnan Colquhoun
 
A Call to Action for Generative AI in 2024
A Call to Action for Generative AI in 2024A Call to Action for Generative AI in 2024
A Call to Action for Generative AI in 2024Results
 
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...Igalia
 
From Event to Action: Accelerate Your Decision Making with Real-Time Automation
From Event to Action: Accelerate Your Decision Making with Real-Time AutomationFrom Event to Action: Accelerate Your Decision Making with Real-Time Automation
From Event to Action: Accelerate Your Decision Making with Real-Time AutomationSafe Software
 
08448380779 Call Girls In Greater Kailash - I Women Seeking Men
08448380779 Call Girls In Greater Kailash - I Women Seeking Men08448380779 Call Girls In Greater Kailash - I Women Seeking Men
08448380779 Call Girls In Greater Kailash - I Women Seeking MenDelhi Call girls
 
Transforming Data Streams with Kafka Connect: An Introduction to Single Messa...
Transforming Data Streams with Kafka Connect: An Introduction to Single Messa...Transforming Data Streams with Kafka Connect: An Introduction to Single Messa...
Transforming Data Streams with Kafka Connect: An Introduction to Single Messa...HostedbyConfluent
 
08448380779 Call Girls In Friends Colony Women Seeking Men
08448380779 Call Girls In Friends Colony Women Seeking Men08448380779 Call Girls In Friends Colony Women Seeking Men
08448380779 Call Girls In Friends Colony Women Seeking MenDelhi Call girls
 
The Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdf
The Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdfThe Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdf
The Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdfEnterprise Knowledge
 
Kalyanpur ) Call Girls in Lucknow Finest Escorts Service 🍸 8923113531 🎰 Avail...
Kalyanpur ) Call Girls in Lucknow Finest Escorts Service 🍸 8923113531 🎰 Avail...Kalyanpur ) Call Girls in Lucknow Finest Escorts Service 🍸 8923113531 🎰 Avail...
Kalyanpur ) Call Girls in Lucknow Finest Escorts Service 🍸 8923113531 🎰 Avail...gurkirankumar98700
 
Salesforce Community Group Quito, Salesforce 101
Salesforce Community Group Quito, Salesforce 101Salesforce Community Group Quito, Salesforce 101
Salesforce Community Group Quito, Salesforce 101Paola De la Torre
 
How to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerHow to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerThousandEyes
 
Automating Business Process via MuleSoft Composer | Bangalore MuleSoft Meetup...
Automating Business Process via MuleSoft Composer | Bangalore MuleSoft Meetup...Automating Business Process via MuleSoft Composer | Bangalore MuleSoft Meetup...
Automating Business Process via MuleSoft Composer | Bangalore MuleSoft Meetup...shyamraj55
 
Presentation on how to chat with PDF using ChatGPT code interpreter
Presentation on how to chat with PDF using ChatGPT code interpreterPresentation on how to chat with PDF using ChatGPT code interpreter
Presentation on how to chat with PDF using ChatGPT code interpreternaman860154
 

Recently uploaded (20)

GenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day PresentationGenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day Presentation
 
Tech-Forward - Achieving Business Readiness For Copilot in Microsoft 365
Tech-Forward - Achieving Business Readiness For Copilot in Microsoft 365Tech-Forward - Achieving Business Readiness For Copilot in Microsoft 365
Tech-Forward - Achieving Business Readiness For Copilot in Microsoft 365
 
Unblocking The Main Thread Solving ANRs and Frozen Frames
Unblocking The Main Thread Solving ANRs and Frozen FramesUnblocking The Main Thread Solving ANRs and Frozen Frames
Unblocking The Main Thread Solving ANRs and Frozen Frames
 
Handwritten Text Recognition for manuscripts and early printed texts
Handwritten Text Recognition for manuscripts and early printed textsHandwritten Text Recognition for manuscripts and early printed texts
Handwritten Text Recognition for manuscripts and early printed texts
 
Histor y of HAM Radio presentation slide
Histor y of HAM Radio presentation slideHistor y of HAM Radio presentation slide
Histor y of HAM Radio presentation slide
 
08448380779 Call Girls In Civil Lines Women Seeking Men
08448380779 Call Girls In Civil Lines Women Seeking Men08448380779 Call Girls In Civil Lines Women Seeking Men
08448380779 Call Girls In Civil Lines Women Seeking Men
 
Breaking the Kubernetes Kill Chain: Host Path Mount
Breaking the Kubernetes Kill Chain: Host Path MountBreaking the Kubernetes Kill Chain: Host Path Mount
Breaking the Kubernetes Kill Chain: Host Path Mount
 
Data Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt RobisonData Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt Robison
 
A Call to Action for Generative AI in 2024
A Call to Action for Generative AI in 2024A Call to Action for Generative AI in 2024
A Call to Action for Generative AI in 2024
 
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...
 
From Event to Action: Accelerate Your Decision Making with Real-Time Automation
From Event to Action: Accelerate Your Decision Making with Real-Time AutomationFrom Event to Action: Accelerate Your Decision Making with Real-Time Automation
From Event to Action: Accelerate Your Decision Making with Real-Time Automation
 
08448380779 Call Girls In Greater Kailash - I Women Seeking Men
08448380779 Call Girls In Greater Kailash - I Women Seeking Men08448380779 Call Girls In Greater Kailash - I Women Seeking Men
08448380779 Call Girls In Greater Kailash - I Women Seeking Men
 
Transforming Data Streams with Kafka Connect: An Introduction to Single Messa...
Transforming Data Streams with Kafka Connect: An Introduction to Single Messa...Transforming Data Streams with Kafka Connect: An Introduction to Single Messa...
Transforming Data Streams with Kafka Connect: An Introduction to Single Messa...
 
08448380779 Call Girls In Friends Colony Women Seeking Men
08448380779 Call Girls In Friends Colony Women Seeking Men08448380779 Call Girls In Friends Colony Women Seeking Men
08448380779 Call Girls In Friends Colony Women Seeking Men
 
The Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdf
The Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdfThe Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdf
The Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdf
 
Kalyanpur ) Call Girls in Lucknow Finest Escorts Service 🍸 8923113531 🎰 Avail...
Kalyanpur ) Call Girls in Lucknow Finest Escorts Service 🍸 8923113531 🎰 Avail...Kalyanpur ) Call Girls in Lucknow Finest Escorts Service 🍸 8923113531 🎰 Avail...
Kalyanpur ) Call Girls in Lucknow Finest Escorts Service 🍸 8923113531 🎰 Avail...
 
Salesforce Community Group Quito, Salesforce 101
Salesforce Community Group Quito, Salesforce 101Salesforce Community Group Quito, Salesforce 101
Salesforce Community Group Quito, Salesforce 101
 
How to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerHow to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected Worker
 
Automating Business Process via MuleSoft Composer | Bangalore MuleSoft Meetup...
Automating Business Process via MuleSoft Composer | Bangalore MuleSoft Meetup...Automating Business Process via MuleSoft Composer | Bangalore MuleSoft Meetup...
Automating Business Process via MuleSoft Composer | Bangalore MuleSoft Meetup...
 
Presentation on how to chat with PDF using ChatGPT code interpreter
Presentation on how to chat with PDF using ChatGPT code interpreterPresentation on how to chat with PDF using ChatGPT code interpreter
Presentation on how to chat with PDF using ChatGPT code interpreter
 

Server Side? Swift

  • 1.  2016/09/10 H-LANE #hackt_h HACKER TACKLE Server Side? Swift
  • 3. • 田中 孝明 (Takaaki Tanaka) • クラスメソッド株式会社 • iOS アプリケーションエンジニア • @kongmingtrap • iOS Developer (Swift / Objective-C) • GyazSquare / GitHub
  • 7. Swift Swift is a powerful and intuitive programming language for macOS, iOS, watchOS and tvOS. Writing Swift code is interactive and fun, the syntax is concise yet expressive, and Swift includes modern features developers love. Swift code is safe by design, yet also produces software that runs lightning-fast.
  • 8. History of Swift • 0.x (2014/06) • 1.0 (2014/09) • 1.1 (2014/10) • 1.2 (2015/02) • 2.0 (2015/06) • 2.1 (2015/10) • 2.2 (2016/03) • 3.0 (2016/09)
  • 9. History of Swift • 0.x (2014/06) • 1.0 (2014/09) • 1.1 (2014/10) • 1.2 (2015/02) • 2.0 (2015/06) • 2.1 (2015/10) • 2.2 (2016/03) • 3.0 (2016/09) 黎明期
  • 10. History of Swift • 0.x (2014/06) • 1.0 (2014/09) • 1.1 (2014/10) • 1.2 (2015/02) • 2.0 (2015/06) • 2.1 (2015/10) • 2.2 (2016/03) • 3.0 (2016/09) 成長期
  • 11. History of Swift • 0.x (2014/06) • 1.0 (2014/09) • 1.1 (2014/10) • 1.2 (2015/02) • 2.0 (2015/06) • 2.1 (2015/10) • 2.2 (2016/03) • 3.0 (2016/09) 全盛期
  • 12. [swift-evolution] Looking back on Swift 3 and ahead to Swift 4 https://lists.swift.org/pipermail/swift-evolution/Week-of-Mon-20160725/025676.html ABI安定化など、Swift 3.0で実装予定だっ た機能が見送られ、Swift 4.0まで持ち越 される。。。
  • 13. Swift is Open Source https://developer.apple.com/swift/blog/?id=34
  • 14. Going Server-side with Swift Open Source https://developer.apple.com/videos/play/ wwdc2016/415/ WWDC2016
  • 17. Agenda • Server Side Swift frameworks • Environment construct • Make • Deploy
  • 18. Server Side Swift frameworks
  • 19.
  • 21. Perfect • Swift における Rails の立ち位置を目指す • 豊富なDB接続ライブラリ • Mustacheテンプレート • FastCGI + apache2 or Nginx
  • 23. VAPOR • Laraval like • シンプルに記述できることを目指す • ドキュメントが丁寧にまとめられている https://github.com/vapor/vapor
  • 25. KITURA • IBM製 • IBMのクラウドプラットフォームBluemixがSwiftに対 応 • サンドボックスで試すことができる • Swift関連の取り組みも熱心 https://github.com/IBM-Swift
  • 36. Build Xcode 8.0 or later OS X El Captan (10.11.6)
  • 37. $ swift —version Apple Swift version 3.0 (swiftlang-800.0.43.6 clang-800.0.38) Target: x86_64-apple-macosx10.9 $ xcode-select --switch /Applications/Xcode.app/Contents/Developer Build
  • 38. $ brew install openssl $ brew link openssl --force Build $ git clone https://github.com/PerfectlySoft/PerfectTemplate.git $ cd PerfectTemplate $ swift build $ .build/debug/PerfectTemplate
  • 39.
  • 40. // Create HTTP server. let server = HTTPServer() // Register your own routes and handlers var routes = Routes() // Add the routes to the server. server.addRoutes(routes) // Set a listen port of 8181 server.serverPort = 8181 // Set a document root. // This is optional. If you do not want to serve static content then do not set this. // Setting the document root will automatically add a static file handler for the route /** server.documentRoot = "./webroot" // Gather command line options and further configure the server. // Run the server with --help to see the list of supported arguments. // Command line arguments will supplant any of the values set above. configureServer(server) do { // Launch the HTTP server. try server.start() } catch PerfectError.networkError(let err, let msg) { print("Network error thrown: (err) (msg)") } Server Start
  • 41. // Create HTTP server. let server = HTTPServer() // Register your own routes and handlers var routes = Routes() // Add the routes to the server. server.addRoutes(routes) // Set a listen port of 8181 server.serverPort = 8181 // Set a document root. // This is optional. If you do not want to serve static content then do not set this. // Setting the document root will automatically add a static file handler for the route /** server.documentRoot = "./webroot" // Gather command line options and further configure the server. // Run the server with --help to see the list of supported arguments. // Command line arguments will supplant any of the values set above. configureServer(server) do { // Launch the HTTP server. try server.start() } catch PerfectError.networkError(let err, let msg) { print("Network error thrown: (err) (msg)") } Server Start
  • 42. // Create HTTP server. let server = HTTPServer() // Register your own routes and handlers var routes = Routes() // Add the routes to the server. server.addRoutes(routes) // Set a listen port of 8181 server.serverPort = 8181 // Set a document root. // This is optional. If you do not want to serve static content then do not set this. // Setting the document root will automatically add a static file handler for the route /** server.documentRoot = "./webroot" // Gather command line options and further configure the server. // Run the server with --help to see the list of supported arguments. // Command line arguments will supplant any of the values set above. configureServer(server) do { // Launch the HTTP server. try server.start() } catch PerfectError.networkError(let err, let msg) { print("Network error thrown: (err) (msg)") } Server Start
  • 43. // Create HTTP server. let server = HTTPServer() // Register your own routes and handlers var routes = Routes() // Add the routes to the server. server.addRoutes(routes) // Set a listen port of 8181 server.serverPort = 8181 // Set a document root. // This is optional. If you do not want to serve static content then do not set this. // Setting the document root will automatically add a static file handler for the route /** server.documentRoot = "./webroot" // Gather command line options and further configure the server. // Run the server with --help to see the list of supported arguments. // Command line arguments will supplant any of the values set above. configureServer(server) do { // Launch the HTTP server. try server.start() } catch PerfectError.networkError(let err, let msg) { print("Network error thrown: (err) (msg)") } Server Start
  • 44. // Create HTTP server. let server = HTTPServer() // Register your own routes and handlers var routes = Routes() // Add the routes to the server. server.addRoutes(routes) // Set a listen port of 8181 server.serverPort = 8181 // Set a document root. // This is optional. If you do not want to serve static content then do not set this. // Setting the document root will automatically add a static file handler for the route /** server.documentRoot = "./webroot" // Gather command line options and further configure the server. // Run the server with --help to see the list of supported arguments. // Command line arguments will supplant any of the values set above. configureServer(server) do { // Launch the HTTP server. try server.start() } catch PerfectError.networkError(let err, let msg) { print("Network error thrown: (err) (msg)") } Server Start
  • 45. Make
  • 46. Router // list routes.add(method: .get, uri: "/list", handler: listHandler) // login routes.add(method: .post, uri: "/login", handler: loginHandler) // get message routes.add(method: .get, uri: "/message", handler: getMessageHandler) // post message routes.add(method: .post, uri: "/message", handler: postMessageHandler) https://github.com/PerfectlySoft/PerfectExample- URLRouting
  • 47. GET Method // listHandler func listHandler(request: HTTPRequest, _ response: HTTPResponse) { defer { response.completed() } response.setHeader(.contentType, value: "application/json") do { let listArray: [String : Any] = [ "name1": 300, "name2": 230.45, "name3": 150 ] try response.setBody(json: listArray) } catch let error as NSError { print(error) } }
  • 48. GET Method curl -v -H "Accept: application/json" -H "Content-type: application/json" - X GET http://0.0.0.0:8181/list * Trying 0.0.0.0... * Connected to 0.0.0.0 (127.0.0.1) port 8181 (#0) > GET /list HTTP/1.1 > Host: 0.0.0.0:8181 > User-Agent: curl/7.43.0 > Accept: application/json > Content-type: application/json > < HTTP/1.1 200 OK < Content-Type: application/json < Connection: Keep-Alive < Content-Length: 40 < * Connection #0 to host 0.0.0.0 left intact {"name1":300,"name2":230.45,"name3":150}
  • 49. GET Method // check thread let thread = Thread.current print(thread) [INFO] Starting HTTP server on 0.0.0.0:8181 with document root ./webroot <NSThread: 0x7fab61c15530>{number = 2, name = (null)} <NSThread: 0x7fab61e06cd0>{number = 3, name = (null)} <NSThread: 0x7fab61f05290>{number = 4, name = (null)} 全てのリクエストが別のThreadで実行さ れていることがわかる
  • 50. POST Method // loginHandler func loginHandler(request: HTTPRequest, _ response: HTTPResponse) { defer { response.completed() } do { let json = try request.postBodyString?.jsonDecode() response.setHeader(.contentType, value: "application/json") guard let decoded = json as? [String : Any] else { return } let result: [String : Any] = decoded["user"].map { ["result": true, "user": $0] } ?? ["result": false] try response.setBody(json: result) } catch let error as NSError { print(error) } }
  • 51. POST Method curl -v -H "Accept: application/json" -H "Content-type: application/json" - X POST -d '{"user": "tana"}' http://0.0.0.0:8181/login * Trying 0.0.0.0... * Connected to 0.0.0.0 (127.0.0.1) port 8181 (#0) > POST /login HTTP/1.1 > Host: 0.0.0.0:8181 > User-Agent: curl/7.43.0 > Accept: application/json > Content-type: application/json > Content-Length: 16 > * upload completely sent off: 16 out of 16 bytes < HTTP/1.1 200 OK < Content-Type: application/json < Connection: Keep-Alive < Content-Length: 29 < * Connection #0 to host 0.0.0.0 left intact {"result":true,"user":"tana"}
  • 53.
  • 54. • Perfect Redis • Perfect SQLite • Perfect PostgreSQL • Perfect MySQL • Perfect MongoDB • Perfect FileMaker DB Connector
  • 55. • Perfect Redis • Perfect SQLite • Perfect PostgreSQL • Perfect MySQL • Perfect MongoDB • Perfect FileMaker DB Connector https://github.com/PerfectlySoft/Perfect-PostgreSQL
  • 56. let package = Package( name: "PerfectTemplate", targets: [], dependencies: [ .Package( url: "https://github.com/PerfectlySoft/ Perfect-PostgreSQL.git", versions: Version(0,0,0)..<Version(10,0,0)) ] ) Postgresql プロジェクト直下のpackage.swiftに Perfect-PostgresSQLを追加する
  • 57. create table message ( id serial primary key, message text, created_at timestamp with time zone, updated_at timestamp with time zone ); • create message table Create Table
  • 58. GET Method // get message routes.add(method: .get, uri: "/message", handler: { request, response in defer { response.completed() } do { response.setHeader(.contentType, value: "application/json") let connection = PGConnection() let status = connection.connectdb(db) let result = connection.exec( statement: "select * FROM message order by updated_at desc") … // DB let db = "postgresql://samplefuku:fukuoka@localhost:5432/exampledb"
  • 59. GET Method… let num = result.numTuples() let messages: [[String : Any]] = (0..<num).map { x in let t1 = result.getFieldString(tupleIndex: x, fieldIndex: 0) let t2 = result.getFieldString(tupleIndex: x, fieldIndex: 1) let t3 = result.getFieldString(tupleIndex: x, fieldIndex: 2) let t4 = result.getFieldString(tupleIndex: x, fieldIndex: 3) let message: [String : Any] = [ "id" : t1, "message" : t2, "created_at" : t3, "updated_at" : t4 ] return message } result.clear() connection.close() try response.setBody(json: ["messages" : messages]) } catch let error as NSError { print(error) } })
  • 60. POST Method // post message routes.add(method: .post, uri: "/message", handler: { request, response in defer { response.completed() } do { let json = try request.postBodyString?.jsonDecode() response.setHeader(.contentType, value: “application/json") guard let decoded = json as? [String : Any] else { return } …
  • 61. POST Method … let result: [String : Any] = decoded["message"].map { message in let connection = PGConnection() let status = connection.connectdb(db) let date = Date() let createdAt = RFC3339DateFormatter.string(from: date) let updatedAt = RFC3339DateFormatter.string(from: date) let result = connection.exec( statement: "insert into message (message, created_at, updated_at) values($1, $2, $3)", params: ["(message)", "(createdAt)", "(updatedAt)"]) result.clear() connection.close() return ["message" : message] } ?? [:] try response.setBody(json: result) …
  • 62. Demo
  • 68. AMI $ sudo ssh -i ~/.ssh/xxxxx.pem ubuntu@xx.xxx.xx.xxx
  • 69. AMI $ wget https://swift.org/builds/development/ubuntu1510/swift-DEVELOPMENT- SNAPSHOT-2016-08-26-a/swift-DEVELOPMENT-SNAPSHOT-2016-08-26-a-ubuntu15.10.tar.gz $ tar xzf swift-DEVELOPMENT-SNAPSHOT-2016-08-26-a-ubuntu15.10.tar.gz https://swift.org/download/#using-downloads AMIにインストールされているのがSwift 2.2のため、 ビルドするためにサポートされているSwift 3.0の SNAPSHOTを取得する $ export PATH=./swift-DEVELOPMENT-SNAPSHOT-2016-08-26-a-ubuntu15.10/usr/bin:"$ {PATH}"
  • 70. Build & Run $ cd PerfectTemplate $ swift build $ .build/debug/PerfectTemplate
  • 71. Demo
  • 73. Call Shell // Commandline func command(launchPath: String, arguments: [String]) -> String { let task = Process() task.launchPath = launchPath task.arguments = arguments let pipe = Pipe() task.standardOutput = pipe task.launch() let data = pipe.fileHandleForReading.readDataToEndOfFile() let output = String( data: data, encoding: String.Encoding.utf8)! return output } let cl = command(launchPath: "/bin/echo", arguments: ["aaaa"])
  • 74. Recap