don't stop believing

[macaron 1] macaron api 시작하기 본문

Swift/Perfect

[macaron 1] macaron api 시작하기

Tongchun 2017. 12. 31. 21:37

사내 인트라넷으로 사용할 macaron의 api 서버를 swift perfect로 만들어 보겠습니다.

인트라넷의 구조는 swift perfect로 api 서버를 만들고 web 서버로 php, 앱은 네이티브로 만들 계획입니다.

macaron api의 개발 가정을 기록해 보겠습니다.


swift 버전부터 확인하겠습니다. 버전은 4.0.3입니다.

1
2
3
$ swift -version
Apple Swift version 4.0.3 (swiftlang-900.0.74.1 clang-900.0.39.2)
Target: x86_64-apple-macosx10.9
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

프로젝트 폴더로 이동해 swift package init으로 초기화 하겠습니다.

1
2
$ cd ~/Documents/macaron-api
$ swift package init --type executable
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

기본 구성의 시작은 Perfect 서버 기본 알이보기와 Perfect 구조 잡기를 기본으로 구성하겠습니다.

[Perfect 서버 기본 알이보기]

[Perfect 구조 잡기]

Perfect 구조 잡기에서 처럼 시작은 main.swift와 controller.swift로 나누겠습니다. main.swift 파일이 있는 위치에 controller.swift를 추가해 줍니다.

1
2
$ cd Sources/macaron-api/
$ touch controller.swift
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

이제 xcode project를 만들어 기본 코딩을 합니다.

1
2
$ swift package generate-xcodeproj
$ open macaron-api.xcodeproj/
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

Package.swift 파일을 열고 아래와 같이 코딩합니다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
// swift-tools-version:3.1.0
// The swift-tools-version declares the minimum version of Swift required to build this package.
import PackageDescription
let package = Package(
name: "macaron-api",
targets: [
Target(
name: "macaron-api",
dependencies: []),
],
dependencies: [
.Package(url: "https://github.com/PerfectlySoft/Perfect-HTTPServer.git", majorVersion: 3),
.Package(url: "https://github.com/PerfectlySoft/Perfect-Mustache.git", majorVersion: 3),
.Package(url: "https://github.com/SwiftORM/StORM.git", majorVersion: 3),
]
)
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

swift 4에서는 SPM에서 swift-tools-version을 지정할 수 있습니다. perfect는 3.1.0을 지원하기 때문에 버전을 지정합니다.

[swift4와 perfect]

main.swift 파일을 열고 아래와 같이 코딩합니다.

api 포트는 1026으로 합니다. webroot 폴더는 아직 안만들었네요.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
import PerfectLib
import PerfectHTTP
import PerfectHTTPServer
import PerfectMustache
let server = HTTPServer()
server.serverPort = 1026
server.documentRoot = "webroot"
let controller = Controller()
server.addRoutes(Routes(controller.routes))
do {
try server.start()
} catch PerfectError.networkError(let err, let msg) {
print("Network error thrown: \(err) \(msg)")
}
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

그 다음은 controller.swift 입니다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
import Foundation
import PerfectLib
import PerfectHTTP
import PerfectHTTPServer
final class Controller {
var routes: [Route] {
return [
Route(method: .get, uri: "/", handler: sayHellobyString),
Route(method: .get, uri: "/json", handler: sayHellobyJson),
Route(method: .get, uri: "/json/second", handler: scondPathJson),
Route(method: .get, uri: "/json/{name}/{age}", handler: urlVariables),
Route(method: .post, uri: "/post", handler: postParam)
]
}
func returnJSONMessage(message: String, response: HTTPResponse) {
do {
try response.setBody(json: ["message": message])
.setHeader(.contentType, value: "application/json")
.completed()
} catch {
response.setBody(string: "Error handling request: \(error)")
.completed(status: .internalServerError)
}
}
func sayHellobyString(request: HTTPRequest, response: HTTPResponse) {
do {
response.setBody(string: "hello tongchun, you are at root directory with get.")
.completed()
} catch {
response.setBody(string: "Error handling request: \(error)")
.completed(status: .internalServerError)
}
}
func sayHellobyJson(request: HTTPRequest, response: HTTPResponse) {
do {
returnJSONMessage(message: "hello tongchun, you are at json directory with get.", response: response)
} catch {
response.setBody(string: "Error handling request: \(error)")
.completed(status: .internalServerError)
}
}
func scondPathJson(request: HTTPRequest, response: HTTPResponse) {
do {
returnJSONMessage(message: "you are at /json/second with get.", response: response)
} catch {
response.setBody(string: "Error handling request: \(error)")
.completed(status: .internalServerError)
}
}
func urlVariables(request: HTTPRequest, response: HTTPResponse) {
do {
guard let userName = request.urlVariables["name"], let userAge = request.urlVariables["age"] else {
response.completed(status: .badRequest)
return
}
returnJSONMessage(message: "Your name is \(userName) and age is \(userAge)", response: response)
} catch {
response.setBody(string: "Error handling request: \(error)")
.completed(status: .internalServerError)
}
}
func postParam(request: HTTPRequest, response: HTTPResponse) {
do {
guard let name = request.param(name: "name"), let age = request.param(name: "age") else {
response.completed(status: .badRequest)
return
}
returnJSONMessage(message: "You sent me by post and data is \(name) / \(age)", response: response)
} catch {
response.setBody(string: "Error handling request: \(error)")
.completed(status: .internalServerError)
}
}
func postJson(request: HTTPRequest, response: HTTPResponse) {
guard let jsonString = request.postBodyString else {
response.completed(status: .badRequest)
return
}
do {
let jsonDic = try jsonString.jsonDecode() as! [String: String]
let userName = jsonDic["name"]!
let userAge = jsonDic["age"]!
returnJSONMessage(message: "Your name is \(userName) and your age is \(userAge)", response: response)
} catch {
response.completed(status: .internalServerError)
return
}
}
}
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

이제 여기서 부터 개발을 시작하겠습니다.



Comments