본문 바로가기

Swift/Perfect

Perfect 라우팅


Perfect 라우팅

1. Routes 
2. HTTP Method, URI 지정 
3. 
Web Root 디렉터리 설정
4. JSON 응답



지난 번에는 Perfect 서버 애플리케이션을 처음 구동해 보았습니다. 

2017/05/17 - [Swift/Perfect] - Perfect 시작하기

이번에는 라우팅 하는 방법에 대해서 알아보려고 합니다 :)


* 참고 *

2017년 5월 현재 Swift 3 / Perfect 최신버전 2.0.x 환경에서 진행함을 알려드립니다.

* Swift 최신 버전 확인

* Perfect 최신 버전 확인


Routes

HTTP 요청에 의해 여러 메서드, URI에 따른 동작을 처리하려면 Routes라는 구조체를 사용합니다.

지난 번 main.swift파일에 서버 포트를 지정해 주었던 server.serverPort = 8080 코드 아래에 routes 변수에 Routes 인스턴스를 하나 할당해줍니다.

var routes = Routes()


HTTP Method, URI 지정

Routes인스턴스를 생성할 때, 원하는 HTTP Method와 URI를 지정할 수 있으며, 요청이 온 경우 handler 클로저를 통해 요청을 처리합니다. 이후, addRoutes() 메서드를 통해 서버에 라우트 정보를 추가해줍니다.

routes.add(method: .get, uri: "/blog", handler: { request, response in
	response.setBody(string: "Blog handler was called")
	response.completed()
})
server.addRoutes(routes)

이렇게 지정하고 실행하면 8080포트blog 경로를 지정하여 요청하면 "Handler was called" 문자열이 돌아오게 될 것입니다.


handler 클로저의 내부에서 request 인스턴스에서 param(name:) 등 많은 메서드를 통해 HTTP 요청 정보를 읽어낼 수도 있습니다. 
routes.add(method: .get, uri: "/blog", handler: { request, response in
    
    let pageToResponse: Int
    
    if let page = request.param(name: "page"), let pageNumber = Int(page) {
        pageToResponse = pageNumber
    } else {
        pageToResponse = 0
    }
    
    response.setBody(string: "Handler was called page number:  \(pageToResponse)")
    response.completed()
})


Web Root 디렉터리 설정

연습을 해봤으니 실질적으로 HTML 응답과 JSON 응답을 해보려합니다. 먼저 웹의 데이터를 모아 둘 WebDocuments 폴더를 사용자 디렉터리의 하위폴더로 생성해줍니다.
> mkdir ~/WebDocuments

WebDocuments 폴더를 생성하면 블로그 메인페이지로 사용할 index.html 파일을 넣어줍니다. (파일을 이동하거나 복사하는 방법에 대해서는 따로 설명하지 않겠습니다... 'ㅁ')

이제 WebDocuments 폴더를 웹서버의 Root 폴더로 지정합니다. 

사용자 디렉터리의 주소를 가져오기 위해 Foundation 프레임워크를 이용했습니다. main.swift 파일 상단에 import Foundation을 통해 Foundation 프레임워크를 불러와주세요.


그리고 아래 코드를  server.addRoutes(routes) 라인 아래에 작성해주세요.

if let homeURL = URL(string: NSHomeDirectory()) {
    var rootPath = homeURL.appendingPathComponent("WebDocuments", isDirectory: true).absoluteString
    
    try Dir(rootPath).create()
    
    server.documentRoot = rootPath
}

이렇게 설정하고 하위 경로 없이 접속하면 WebDocuments 폴더의 index.html 파일을 자동으로 메인 페이지로 볼 수 있습니다.




JSON 응답

이번에는 단순히 HTML 웹페이지가 아닌 JSON 응답을 줘보려고 합니다. 먼저 응답을 제어하기 위한 handler 클로저를 따로 함수로 구현하려 합니다. 가독성 면에서도 그게 좋을 것 같아요.


서버 인스턴스 생성코드 let server = HTTPServer() 전에 handler 함수를 구현해봅니다. 

func jsonHandler(request: HTTPRequest, response: HTTPResponse) {
    
    var jsonDictionary: [String: Any] = [:]
    jsonDictionary["name"] = "yagom"
    jsonDictionary["languages"] = ["Swift", "Objective-C"]
    jsonDictionary["age"] = 10
    jsonDictionary["alive"] = true
    
    do {
        response.setHeader(.contentType, value: "application/json; charset=utf-8")
        try response.setBody(json: jsonDictionary)
        response.completed()
    } catch {
        response.completed(status: .internalServerError)
    }
}


그리고 경로를 지정해주기 위해서 server.addRoutes(routes) 코드 위에 아래 코드를 작성합니다.

routes.add(method: .get, uri: "/json", handler: jsonHandler(request:response:))



다시 실행해서 /json 경로로 GET 요청을 하면 아래와같이 JSON 문자열을 응답한 것을 확인할 수 있습니다.




정리

지금까지 작성한 main.swift 파일 코드

import PerfectLib
import PerfectHTTP
import PerfectHTTPServer
import Foundation

func jsonHandler(request: HTTPRequest, response: HTTPResponse) {
    
    var jsonDictionary: [String: Any] = [:]
    jsonDictionary["name"] = "yagom"
    jsonDictionary["languages"] = ["Swift", "Objective-C"]
    jsonDictionary["age"] = 10
    jsonDictionary["alive"] = true
    
    do {
        response.setHeader(.contentType, value: "application/json; charset=utf-8")
        try response.setBody(json: jsonDictionary)
        response.completed()
    } catch {
        response.completed(status: .internalServerError)
    }
}

let server = HTTPServer()

server.serverPort = 8080
var routes = Routes()
routes.add(method: .get, uri: "/blog", handler: { request, response in
    
    let pageToResponse: Int
    
    if let page = request.param(name: "page"), let pageNumber = Int(page) {
        pageToResponse = pageNumber
    } else {
        pageToResponse = 0
    }
    
    response.setBody(string: "Handler was called page number:  \(pageToResponse)")
    response.completed()
})

routes.add(method: .get, uri: "/json", handler: jsonHandler(request:response:))

server.addRoutes(routes)


if let homeURL = URL(string: NSHomeDirectory()) {
    var rootPath = homeURL.appendingPathComponent("WebDocuments", isDirectory: true).absoluteString
    
    try Dir(rootPath).create()
    
    server.documentRoot = rootPath
}

do {
    try server.start()
} catch PerfectError.networkError(let error, let message) {
    Log.error(message: "Error: \(error), \(message)")
}


---------------------------------

물론 이 외에도 정말 많은 응용 방법과 라우트 하는 방법, 더 다양한 기능들이 있지만 모두 설명할 수 없으므로 정말 간단하게 감을 잡을 수 있는 정도만 해봤습니다. 차후에 간단한 프로젝트를 통해서 필요한 부분은 조금씩 더 설명하려고 합니다.


이정도 만들어 봤으면 대강 핑퐁은 해봤으니, 작은 미니 프로젝트 한 번 시작해 봐도 되지 않을까요?

다음 번에는 미니 프로젝트를 시작해볼 예정입니다~


다음에 또 만나요! :D


참고문서

* PerfectDocs - Routing

* PerfectDocs - HTTPResponse

* PerfectDocs - JSON Converter



by yagom

facebook : http://www.facebook.com/yagomSoft

facebook group : https://www.facebook.com/groups/yagom

p.s 제 포스팅을 RSS 피드로 받아보실 수 있습니다.

RSS Feed 받기   


↓↓↓ 블로거에게 공감은 큰 힘이 됩니다 ↓↓↓ 




'Swift > Perfect' 카테고리의 다른 글

사진 게시판 API 만들기 [3]  (0) 2017.08.09
사진 게시판 API 만들기 [2]  (0) 2017.07.11
사진 게시판 API 만들기 [1]  (6) 2017.06.27
Perfect 시작하기  (0) 2017.05.17
우분투(Ubuntu)에 스위프트 설치하기  (2) 2017.04.03