'2017/09/13'에 해당되는 글 1건

  1. 2017.09.13 사진 게시판 API 만들기 [6]


Perfect 미니 프로젝트 [6]

1. 게시물 삭제 API


CRUD 중 마지막! Delete에 해당하는 API를 만들어 봅니다!!


참고

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

* Swift 최신 버전 확인(https://github.com/apple/swift/releases)

* Perfect 최신 버전 확인(https://github.com/PerfectlySoft/Perfect/releases)


지난 내용 돌아보기

2017/06/27 - [Swift/Perfect] - 사진 게시판 API 만들기 [1]

2017/07/11 - [Swift/Perfect] - 사진 게시판 API 만들기 [2]

2017/08/09 - [Swift/Perfect] - 사진 게시판 API 만들기 [3]

2017/08/30 - [Swift/Perfect] - 사진 게시판 API 만들기 [4]

2017/09/06 - [Swift/Perfect] - 사진 게시판 API 만들기 [5]



게시물 삭제 API


지난 번에 올려둔 게시물을 삭제하는 API를 구성해보려고 합니다. 일단 처음 라우팅 해 둔대로 게시물 내용을 수정하는 API의 핸들러는 deleteArticleHandler(request:response:) 함수입니다. 게시물을 삭제하는 API 데이터 모양을 살펴볼까요?

요청(Request)

  • HTTP Method : DELETE
  • Content-Type: application/json

매개변수 없음


응답(Response)

Key 

자료형 

비고 

필수여부 

article_id

string

삭제된 게시물 고유 식별자

Y




HTTP DELETE 메서드로 URI Path를 통해 게시물 ID를 전달하면 게시물을 삭제한 후 게시물 ID를 응답으로 주면 끝입니다! 어려울 것 없어보여요!  

한 번 함께해보시죠 :)

( 이전 API들과 중복 코드가 많지만 포스팅에서 이전 내용을 수정하는 것이 여긴 귀찮은 것이 아니므로... 일단 중복되는 코드가 많아도 꾸역꾸역 구현해 봤습니다. 차후에 여러분 스스로 중복 코드를 줄여보세요 :D )


API 핸들러의 코드를 작성하기 위해 Souces/handlers.swift 파일의 deleteArticleHandler(request:response:) 함수 내부에 코드를 작성해봅니다.


우선 요청정보를 통해 게시물 고유번호를 받아보겠습니다.

    // 응답 컨텐츠 형식은 JSON
    response.setHeader(.contentType, value: ContentsType.json)
    
    // 요청 경로에서 이미지 고유번호를 가져옵니다
    guard let articleId: String = request.pathComponents.last else {
        sendCompleteResponse(response, status: .badRequest, jsonBody: [JSONKey.message:"need article id"])
        return
    }

이제 가져온 게시물 고유번호를 통해 MongoDB에서 문서를 찾아야합니다. find 메서드를 사용하여 쿼리를 보내면 DB는 커서정보를 보내줍니다. 이 커서는 우리가 파일탐색기에서 커서를 옮겨가며 파일을 지정하는 것처럼 DB에 저장되어있는 문서의 위치를 지정하여 가리키는 정보입니다. 위의 코드 아래에 이어서 작성합니다.
    // MongoDB에서 문서를 찾으려면 쿼리를 위한 BSON 객체를 만들 필요가 있습니다.
    // 새로 생성한 BSON 객체에 고유번호를 넣어서 쿼리 객체를 생성합니다
    let query: BSON = BSON()
    let oid: BSON.OID = BSON.OID(articleId)
    query.append(oid: oid)

    // 사용한 BSON 문서는 나중에 닫아줍니다
    defer {
        query.close()
    }
    
    // DB 컬렉션에 쿼리를 전송하여 해당 문서를 가리키는 커서를 가져옵니다
    guard let cursor: MongoCursor = DB.collection?.find(query: query, limit: 1) else {
        sendCompleteResponse(response, status: .badRequest, jsonBody: [JSONKey.message:"wrong article id"])
        return
    }


커서가 가리키는 문서, 즉, 우리가 DB에서 찾은 문서의 정보를 토대로 이미지도 삭제하고 DB에서 문서도 삭제합니다.
    do {
        // 커서가 가리키는 문서를 쭉 돌면서 수행됩니다
        try cursor.enumerated().forEach { (pair: (offset: Int, element: BSON)) in
            
            // 사용한 BSON 문서는 나중에 닫아줍니다
            defer {
                pair.element.close()
            }
            
            // DB 문서를 JSON 문자열로 변환 한 후 디코드하여 딕셔너리 인스턴스로 변경해줍니다
            guard let article: [String : Any] = try pair.element.asString.jsonDecode() as? [String : Any] else {
                sendCompleteResponse(response, status: .internalServerError, jsonBody: [JSONKey.message:"can not find article from DB"])
                return
            }
           
            // mongoDB 컬렉션 가져오기
            guard let collection = DB.collection else {
                sendCompleteResponse(response, status: .internalServerError, jsonBody: [JSONKey.error:"data base initialize failed"])
                return
            }
            
            // 컬렉션에서 게시물 정보에 해당하는 문서를 삭제합니다
            let result: MongoCollection.Result = collection.remove(selector: pair.element)
          
            // 삭제 결과를 토대로 성공/실패여부를 판단합니다.
            switch result {
                
            // 게시물 정보 삭제 성공
            case .success:
                // DB에 저장되어있던 이미지경로
                guard let imagePath = article[JSONKey.imagePath] as? String else {
                    sendCompleteResponse(response, status: .internalServerError, jsonBody: [JSONKey.message:"can not image path from DB"])
                    return
                }
                
                // 이미지경로에 존재하는 파일을 삭제합니다
                File(imagePath).delete()
                
            // 게시물 정보 삭제 실패
            case .error(let errorCode, let errorCode2, let message):
                sendCompleteResponse(response, status: .internalServerError, jsonBody: [JSONKey.error:"\(errorCode), \(errorCode2): \(message)"])
                return
            
            // 그 외 다른 응답
            default:
                sendCompleteResponse(response, status: .internalServerError, jsonBody: [JSONKey.error:"wrong transaction"])
                return
            }
            
            // 모든 작업을 완료하고 JSON 응답
            sendCompleteResponse(response, status: .ok, jsonBody: [JSONKey.articleId:articleId])

        }
    } catch {
        // 도중에 오류가 생겼다면 오류 전달
        sendCompleteResponse(response, status: .internalServerError, jsonBody: [JSONKey.error:error.localizedDescription])
        return
    }

삭제는 사실 간단하면서도 고려해야 할 점이 많습니다. 이미지를 먼제 삭제하고 DB 문서를 삭제할 것인지, 문서를 먼저 삭제하고 이미지를 삭제할 것인지. 등등, 잘 고민해보세요 :)


동작 테스트를 해봅니다.

삭제 후 정상적으로 게시물 ID가 전송된 것을 확인할 수 있습니다!


이제 CRUD가 다 끝났군요! 

다음엔 무엇을 해볼까요? 아직은 계획이 없습니다 :)

필요한 정보가 있다면 언제든 요청주세요!



오늘은 여기까지~!

다음에 또 만나요~~ :D



참고문서





by yagom

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

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

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

RSS Feed 받기   


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




저작자 표시 비영리 변경 금지
신고

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

사진 게시판 API 만들기 [6]  (0) 2017.09.13
사진 게시판 API 만들기 [5]  (0) 2017.09.06
사진 게시판 API 만들기 [4]  (0) 2017.08.30
사진 게시판 API 만들기 [3]  (0) 2017.08.09
사진 게시판 API 만들기 [2]  (0) 2017.07.11
사진 게시판 API 만들기 [1]  (6) 2017.06.27
Posted by yagom


티스토리 툴바