-
raywenderlich - Kitura Tutorial카테고리 없음 2019. 4. 9. 11:48
raywenderlich - Kitura Tutorial
학습 링크: raywenderlich - Kitura Tutorial
목표
- 백엔드 API를 처음부터 만듭니다.
- API를 로컬 컴퓨터에서 실행중인 CouchDB 인스턴스에 연결하십시오
- 할당
Get
,Post
그리고DELETE
모델 객체의 사용
결과
열심히 따라 했으나 내가 원하는 결과가 아닙니다!
Learn how to build a back-end for the Apple FoodTracker iOS application
이걸 보고 다시 정리 고고슁
Docker 설치
brew install docker
설치하고 Docker에는 사용 못함ㅋㅋㅋㅋ
CouchDB 설치
brew install couchdb
Couch DB 실행
brew services start couchdb
Couch DB 중지brew services stop couchdb
Kitura 자습서 프로젝트 만들기
brew tap ibm-swift/kitura brew install kitura kitura init
Swift 실행 패키지 만들기
mkdir KituraTIL cd KituraTIL swift package init --type executable
패키지 열기
open -a Xcode Package.swift
패키지 내용 수정 dependencies 안에는 2, 3, 4 와 같이 의존 관계를 패키지로 선언하고 각각의 역활은 Kitura.git Kitura의 사용
HeliumLogger.git 백엔드 로깅 프레임워크
Kitura-CouchDB.git Kitura가 CouchDB와 통신 할 수 있게 해줌
// swift-tools-version:5.0 // The swift-tools-version declares the minimum version of Swift required to build this package. import PackageDescription let package = Package( name: "KituraTIL", dependencies: [ // Dependencies declare other packages that this package depends on. // .package(url: /* package url */, from: "1.0.0"), // 2 .package(url: "https://github.com/IBM-Swift/Kitura.git", .upToNextMajor(from: "2.0.0")), // 3 .package(url: "https://github.com/IBM-Swift/HeliumLogger.git", .upToNextMajor(from: "1.0.0")), // 4 .package(url: "https://github.com/IBM-Swift/Kitura-CouchDB.git", .upToNextMajor(from: "3.0.0")) ], targets: [ // Targets are the basic building blocks of a package. A target can define a module or a test suite. // Targets can depend on other targets in this package, and on products in packages which this package depends on. .target(name: "KituraTIL", dependencies: ["Kitura" , "HeliumLogger", "CouchDB"], path: "Sources") .testTarget( name: "KituraTILTests", dependencies: ["KituraTIL"]), ] )
빌드 하기 swift 4.2.1보다 높아야 정상적으로 가능함
swift build
Xcode로 프로젝트 변환
swift package generate-xcodeproj xed .
swift 5.0 업데으로 인한 오류
전체 빌드 옵션도 4.2로 바꿔주고 Xcode 버전도 10.1이여야하구
각 타켓에서 swift Language Version이 5면 수정한다
정상 빌드 - 실행 되고 Hello, world! 나오면 성공
Kitura 서버 설정
Application.swift 파일 추가 그림과 같이 그룹 경로 잘 추가해서 넣어주세요
라우터 처리 라우터는 해당되는 엔드 포인트! 즉 localhost:8080 포트를 통해 요청을 처리한다는 말
import Kitura import LoggerAPI public class App { // 1 let router = Router() public func run() { // 2 Kitura.addHTTPServer(onPort: 8080, with: router) // 3 Kitura.run() } }
Hello, world!가 출력되면 main.swift에 가서 App 클래스 생성
import Kitura import HeliumLogger import LoggerAPI HeliumLogger.use() let app = App() app.run()
Xcode에서 실행하고 localhost:8080 에 접속하면 로컬 시스템에서 Swift 기반 HTTP 서버를 실행하는 중
모델생성
Acronym.swift 생성. 타겟은 KituraTIL
내용은 아래와 같이 코드로 정의 CouchDB를 사용 하기 위해서는 구조체가
Document
를 따라야합니다.Document
를 따르게 되면 Codable Routing 과 CouchDB 사용가능// 1 import CouchDB // 2 struct Acronym: Document { // 3 let _id: String? // 4 var _rev: String? // 5 var short: String var long: String }
CouchDB 연결
Application .swift를 열고 다음과 같이 변경
// // Application.swift // KituraTIL // // Created by 이규현 on 09/04/2019. // // 1 import CouchDB import Foundation import Kitura import LoggerAPI public class App { // 2 var client: CouchDBClient? var database: Database? let router = Router() private func postInit() { //MARK: 구성 값을 저장하고, let connectionProperties = ConnectionProperties(host: "localhost", port: 5984, secured: false) //MARK: 새 값을 지정하는데 사용하는 오브젝트를 작성 client = CouchDBClient(connectionProperties: connectionProperties) //MARK: 일치하는 값이 이미 있으면 기존 데이터를 겹쳐 쓰지 않음 client!.retrieveDB("acronyms") { database, error in guard let database = database else { //MARK: 데이터베이스가 없으면 createNewDatabase 호출함 Log.info("Could not retrieve acronym database: " + "\(String(describing: error?.localizedDescription)) " + "- attempting to create new one.") self.createNewDatabase() return } //MARK: 데이터베이스 존재하면 finalizeRoutes 경로를 구성하기 위해 호출함 Log.info("Acronyms database located - loading...") self.finalizeRoutes(with: database) } } private func createNewDatabase() { //MARK: "acronyms" 주어진 이름으로 데이터베이스를 생성함. client?.createDB("acronyms") { database, error in //MARK: 데이터베이스가 존재하는지 확인, guard let database = database else { Log.error("Could not create new database: " + "(\(String(describing: error?.localizedDescription))) " + "- acronym routes not created") return } self.finalizeRoutes(with: database) } } private func finalizeRoutes(with database: Database) { // 5 } public func run() { // 6 postInit() Kitura.addHTTPServer(onPort: 8080, with: router) Kitura.run() } }
데이터 베이스의 유지?
AcronymPersistence.swift 파일 생성
코드 내용 수정 GET, POST, DELETE 를 추가함
// // AcronymPersistence.swift // KituraTIL // // Created by 이규현 on 09/04/2019. // import Foundation import CouchDB import LoggerAPI extension Acronym { class Persistence { static func getAll(from database: Database, callback: @escaping (_ acronyms: [Acronym]?, _ error: Error?) -> Void) { database.retrieveAll(includeDocuments: true) { documents, error in guard let documents = documents else { Log.error("Error retrieving all documents: \(String(describing: error))") return callback(nil, error) } let acronyms = documents.decodeDocuments(ofType: Acronym.self) callback(acronyms, nil) } } static func save(_ acronym: Acronym, to database: Database, callback: @escaping (_ acronym: Acronym?, _ error: Error?) -> Void) { database.create(acronym) { document, error in guard let document = document else { Log.error("Error creating new document: \(String(describing: error))") return callback(nil, error) } database.retrieve(document.id, callback: callback) } } static func delete(_ acronymID: String, from database: Database, callback: @escaping (_ error: Error?) -> Void) { database.retrieve(acronymID) { (acronym: Acronym?, error: CouchDBError?) in guard let acronym = acronym, let acronymRev = acronym._rev else { Log.error("Error retrieving document: \(String(describing:error))") return callback(error) } database.delete(acronymID, rev: acronymRev, callback: callback) } } } }
Codabel Routes 만들기?
AcronymRoutes.swift 추가
AcronymRoutes.swift 코드 수정 GET를 요청하게 되면
localhost:8080/acronyms
POST를 요청하게 되면localhost:8080/acronyms
DELETE 요청하면localhost:8080/acronyms/id
// // AcronymRoutes.swift // KituraTIL // // Created by 이규현 on 09/04/2019. // import CouchDB import Kitura import KituraContracts import LoggerAPI // 1 private var database: Database? func initializeAcronymRoutes(app: App) { // 2 database = app.database // 3 app.router.get("/acronyms", handler: getAcronyms) app.router.post("/acronyms", handler: addAcronym) app.router.delete("/acronyms", handler: deleteAcronym) } //MARK: GET 핸들러 private func getAcronyms(completion: @escaping ([Acronym]?, RequestError?) -> Void) { guard let database = database else { return completion(nil, .internalServerError) } Acronym.Persistence.getAll(from: database) { acronyms, error in return completion(acronyms, error as? RequestError) } } //MARK: POST 핸들러 private func addAcronym(acronym: Acronym, completion: @escaping (Acronym?, RequestError?) -> Void) { guard let database = database else { return completion(nil, .internalServerError) } Acronym.Persistence.save(acronym, to: database) { newAcronym, error in return completion(newAcronym, error as? RequestError) } } //MARK: DELETE 핸들러 private func deleteAcronym(id: String, completion: @escaping (RequestError?) -> Void) { guard let database = database else { return completion(.internalServerError) } Acronym.Persistence.delete(id, from: database) { error in return completion(error as? RequestError) } }
Application.swift를 열고 finalizeRoutes 내용 채우기
GET, POST, DELETE 작업이 끝나고 하는 행위
self.database = database initializeAcronymRoutes(app: self) Log.info("Acronym routes created")
API 테스트
GET 요청
curl http://localhost:8080/acronyms
POST 보내기
curl -X POST http://localhost:8080/acronyms -H 'content-type: application/json' -d '{"short": "BRB", "long": "Be right back"}'
GET 요청
curl http://localhost:8080/acronyms
결과값
[{"_id":"8ac95fdc6873eb5a40f5cf27e9000e78","_rev":"1-19e2bfb638a5bc5cb52377a37678c3a8","short":"BRB","long":"Be right back"}]%
내가 원한건..
POST는 오케이 GET할때 특정 아이디로 조회
댓글