'몽고'에 해당되는 글 1건

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


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]  (8) 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

댓글을 달아 주세요

  1. 치맥이집사 2018.02.02 11:02  댓글주소  수정/삭제  댓글쓰기

    야곰님 안녕하세요. 개발자 없이 창업자 셋이서 개발 배우며 런칭하려고 준비 중입니다. 처음부터 공부해서 차근히 하면 좋겠지만, 공부와 동시에 앱을 만들고자 하여서 앱에 적용될 기능 위주로 공부하고있습니다.
    야곰님 블로그 참고해서 보려고 들어왔다가 혹시 괜찮으시다면 여쭈어볼게 있어서 댓글 남깁니다. (요청글이나 야곰님한테 하고싶은 말이 있을 때 어디다가 남겨야할지 몰라서 댓글로 남기게 되었어요ㅜㅜ)

    사용자가 사진을 올리고, 올린 사진 리스트 중에 본인이 마음에 드는 사진에 좋아요처럼 투표를 할 수 있고 사용자 모두 몇개의 좋아요를 받았는지 볼 수 있으며, 투표 결과에 따라 1등은 소정의 사은품을 주는 커뮤니티 앱을 구상하고 있습니다.

    구글이랑 깃허브에서 vote app swift, ranking app swift 등등 투표와 관련된 키워드로 검색해보았는데 비슷한 기능을 하는 오픈소스를 찾지 못했어요 ㅜㅜ

    혹시 야곰님께서 위의 기능과 비슷한 오픈소스나 강좌 등을 알고 계시면 댓글 부탁드려도 될까요?

    야곰님 책도 나오신걸로 아는데 혹시 책이 정식으로 공부하기 위한 책인지, 아니면 예제집 처럼 실전에서 바로 적용할 수 있는 책인지 궁금합니다.
    문법부터 공부하는 학생이 아니라서 실전에 사용될 수있는 예제나 소스가 많은 책을 찾고 있습니다.

    • Favicon of https://blog.yagom.net BlogIcon yagom 2018.02.04 09:02 신고  댓글주소  수정/삭제

      안녕하세요 치맥이집사님,

      치맥이집사님께서 구상한 기능은 iOS 클라이언트 외에 서버도 따로 구현해야 하는 상황이라고 생각합니다. iOS에서는 주로 사진 선택과 전송 등 사용자 UI쪽에 치중한 작업을 주로 구현하고 사진 저장 및 커뮤니티 기능은 서버에서 구현하게됩니다.

      그런데 그 원하는 기능을 모두 구현하는 서버는 오픈소스 한 두가지로 충족할 수 있는 부분은 아닙니다. 서버사이드 프레임워크를 공부한 후 많은 부분을 직접 구현해야 할 것으로 보입니다. 또, 스위프트 서버사이드 프레임워크는 아직 크게 활성화되지 못하였기 때문에 관련 오픈 라이브러리를 찾는 일은 더 어려울 것으로 보입니다. 다른 언어와 프레임워크를 사용하는 것이 더 나을 것으로 생각합니다.

      또, iOS에서 사진에 접근하고 가져오는 기능을 구현하고 싶다면 Photos 또는 PhotosUI 프레임워크에 대해 찾아보시고, 관련 오픈 라이브러리를 찾아보시는 것이 좋겠습니다.

      지금 나와이있는 제 책은 스위프트 문법에 관한 책으로, 실전에서 바로 사용가능한 예제코드가 수록되어 있지는 않습니다. 아마 실전에서 바로 사용할 수 있는 코드가 수록된 책은 없다고 보셔도 무방할 것 같습니다.

  2. 치맥이집사 2018.02.10 14:30  댓글주소  수정/삭제  댓글쓰기

    야곰님 안녕하세요. 상세한 답변 감사합니다.

    혹시 요즘 오프라인 강좌나 온라인 강좌 지속적으로 하고 계신가요?

    유료라도 강좌 듣고싶습니다~!

    • Favicon of https://blog.yagom.net BlogIcon yagom 2018.02.11 00:40 신고  댓글주소  수정/삭제

      안녕하세요 치맥이집사님,

      늦어도 3월 중에는 온라인에서 찾아 뵐 수 있을 것 같습니다. 아직 확실하진 않으니, 확정이 되면 페이스북으로 소식 전하도록 하겠습니다 :)

      https://www.facebook.com/yagompage/
      https://www.facebook.com/yagomsoft

      새해 복 많이 받으세요.

  3. Favicon of https://www.mallmoney.co.kr/ BlogIcon 소액결제현금 2018.10.16 11:19  댓글주소  수정/삭제  댓글쓰기

    감사합니다 ~~~~~~