상황 설명 -
결제 API를 구성하고 테스트하는 도중 401에러가 발생 했었습니다.
정확한 에러 내용은 공개할 수 없지만,요청
이 잘못 되었다는 대략적인 내용입니다.Encoding 모델이 잘못되었거나, 요청할 때 빠진 부분이 있는 건지 확인하는데 많은 시간을 소모했습니다. 문제의 원인은 다음과 같았습니다…
encoder.keyEncodingStrategy = .convertToSnakeCase
인스턴스를 Json 형식으로 바꾸는 것? 알죠 알죠~!
struct Person: Encodable {
var firstName: String
var lastName: String
}
Swift에서는 JSONEncoder를 사용해 Encodable 타입의 인스턴스를
JSON 데이터로 변환할 수 있습니다.
모델의 프로퍼티를 JSON 키와 매칭시키고, 해당 데이터를 JSON 형식의 Data 객체로 만들어 줍니다.
let encoder = JSONEncoder()
let person = Person(firstName: "Bren", lastName: "Din")
let jsonData = try encoder.encode(person)
JSONEncoder님은 옵션이 있으셔요!
.useDefaultKeys
:
- 기본 설정으로,
Codable
구조체나 클래스의 프로퍼티 이름을 JSON의 키로 직접 사용합니다.- 예:
struct { var firstName: String }
는 JSON에서{"firstName": "value"}
로 인코딩됩니다..convertToSnakeCase
:
- 프로퍼티 이름을 스네이크 케이스(Snake Case)로 변환하여 JSON 키로 사용합니다.
이는 일반적으로 카멜 케이스(Camel Case)로 작성된 프로퍼티 이름을 스네이크 케이스로 자동 변환해 주며, 주로 백엔드 API와의 연동 시 사용됩니다.- 예:
struct { var firstName: String }
는 JSON에서{"first_name": "value"}
로 인코딩됩니다..custom((CodingKey) -> CodingKey)
:
- 클로저를 통해 각 프로퍼티의 이름을 원하는 방식으로 매핑할 수 있습니다.
클로저는 각CodingKey
에 대해 호출되며, 클로저에서 반환한CodingKey
를
JSON 키 이름으로 사용합니다.
저는 해당 인코딩 모델에서 코딩키를 통해 이름을 정의해 사용하고 있었습니다.
// 결제 영수증 검증
struct PaymentsModel: Codable {
let impUID: String
let postID: String
let productName: String
var price: Int
enum CodingKeys: String, CodingKey {
case impUID = "imp_uid"
case postID = "post_id"
case productName
case price
}
init(impUID: String, postID: String, productName: String, price: Int) {
self.impUID = impUID
self.postID = postID
self.productName = productName
self.price = price
}
init(from decoder: any Decoder) throws {
let container = try decoder.container(keyedBy: CodingKeys.self)
self.impUID = try container.decode(String.self, forKey: .impUID)
self.postID = try container.decode(String.self, forKey: .postID)
self.productName = try container.decode(String.self, forKey: .productName)
self.price = try container.decode(Int.self, forKey: .price)
}
}
해당 코드를 인코딩할 때, 카멜 케이스 설정을 주면 어떻게 될까요?
let impUID: String
let postID: String
let productName: String
var price: Int
enum CodingKeys: String, CodingKey {
case impUID = "imp_uid"
case postID = "post_id"
case productName
case price
}
위의 코드에서
case impUID = "imp_uid"
case postID = "post_id"
이 두 친구는 문제가 발생하지 않았습니다.
그런데, let productName: String
부분은 어떻게 될까요?
productName 키는 카멜 케이스에서 스네이크 케이스로 변환되어
"product_name"으로 바뀌게 됩니다.
내가 바라지도 않았었는데...>!!!!!
encoder.keyEncodingStrategy = .useDefaultKeys
개발 과정에서 발생하는 간단한 실수가 예상치 못하게 시간이 길어졌습니다.. ㅠㅠ
실제 회사 프로젝트 였다면 더 큰 문제로 이어질 수 있었을거라고 생각합니다.
이번 경우처럼, JSONEncoder
의 keyEncodingStrategy
설정이 잘못되어
예상치 못한 API 오류를 유발한 것은, 자칫 큰 프로젝트 지연의 원인이 될 수 도 있구요
단순히 새로운 기술을 익히는 것 뿐만 아니라, 기존의 기술들 을 충분히 이해 하고 작업할
능력이 필요 하겠구나 를 다시한번 생각하게 하는 시간이였습니다.