웹 개발에 있어서 클라이언트의 요청에 문제가 있을 때, 서버에서 클라이언트에게 어떤 에러 응답을 보여줄 것인지는 매우 중요한 부분이라고 생각한다.
그래서 에러처리와 관련하여 조사하던 중 발견한 qiita의 'WebAPIでエラーをどう表現すべき?15のサービスを調査してみた'을 개인적인 공부를 위해 번역하고자 한다.
이 게시글은 15개의 글로벌 웹 서비스의 에러 응답을 비교하는 것을 주 내용으로 하고 있으며, 웹 서비스들이 어떤 패턴으로 에러응답을 하고 있는지 가볍게 보면 좋을 듯하다.
이번 Web API에 대하여 조사한 웹 서비스는 아래 15개의 서비스이다. 생각난 순서대로 조사했기 때문에 순서에는 의미가 없다.
그러면 각각의 서비스가 Web API에서 에러를 JSON으로 어떻게 표현하고 있는지 확인해 보자.
{
"message": "Validation Failed",
"errors": [
{
"resource": "Issue",
"field": "title",
"code": "missing_field"
}
]
}
전형적인 에러는 message 뿐이기에 심플하지만, errors에서 복수의 에러가 보여지고, 상세 에러를 표현하는 것이 가능한 구조로 되어 있다.
{
"error": {
"message": "Message describing the error",
"type": "OAuthException",
"code": 190,
"error_subcode": 460,
"error_user_title": "A title",
"error_user_msg": "A message"
}
}
Facebook의 특징은 엔드유저용의 메시지가 별도로 있는 것이다. 밖에도 요청하는 장소에 맞춰서 번역까지 해주기 떄문에 어플을 만드는 쪽에서 굉장히 편리하다.
{
"id": "rate_limit",
"message": "Your account reached the API rate limit\nPlease wait a few minutes before making new requests",
"url": "https://devcenter.heroku.com/articles/platform-api-reference#rate-limits"
}
Heroku는 극단적으로 심플한 형식이지만, 에러에 대한 설명이 있는 페이지의 url이 같이 있는 것이 특징 중에 하나이다.
{
"error": {
"message":"We are sorry, this Error should never happen to you",
"tip":"Please contact support@toggl.com with information on your request",
"code":500
}
}
Toggl의 특징은 에러를 어떻게 처리하면 좋을지 간단한 힌트가 있다는 점이다.
{
"Error" : {
"Message" : "error message"
}
}
Yahoo!의 API는 에러 메세지만을 응답하는 것으로 되어 있다.
{
"code":1001,
"message":"Message API (batch type) to same user is called
several times by official user in a certain period of time. Service unavailable.",
"ref_url":"http:\/\/docs.developer.gree.net\/error.html"
}
GREE의 에러 응답도 Heroku와 같이 심플한 형식이지만 에러에 대한 설명이 있는 페이지의 URL이 있다는 것이 특징 중 하나이다.
{
"requestId": "-1712857370761229397",
"errors": [
{
"code": 90,
"message": "Invalid format: Start Date must follow format yyyy-mm-dd"
},
{
"code": 100,
"message": "Invalid format: End Date must follow format yyyy-mm-dd"
},
{
"code": 110,
"message": "Invalid Format: count must be greater than or equal to 1"
}
]
}
Nike는 요청 ID가 있어 개발자가 API 프로바이더에 질문했을 때, 이용되는 것이라고 생각된다. 또한 복수의 에러를 응답할 수 있도록 되어 있다는 특징이 있다.
{
"errors": [
{
"message": "Sorry, that page does not exist",
"code": 34
}
]
}
Twitter의 API의 에러 응답은 에러가 배열에 담겨 있어 복수의 에러를 응답할 수 있도록 설계되어 있는 점이 특징이다.
{
"error": {
"errors": [
{
"domain": "global",
"reason": "appNotConfigured",
"message": "The app with id {appId} does not exist or is not properly configured as a Google Drive app."
}
],
"code": 403,
"message": "The app with id {appId} does not exist or is not properly configured as a Google Drive app."
}
}
Google의 특징은 다양한 서비스를 아우루는 통일된 형식의 JSON을 사용하고 있다는 점이다. 그래서 서비스를 보여주기 위해서 domain 필드가 설계되어 있다. 또한, 복수의 에러를 응답할 수 있도록 errors 필드가 배열로 되어 있다.
{
"status": 400,
"message": "No to number is specified",
"code": 21201,
"more_info": "http:\/\/www.twilio.com\/docs\/errors\/21201"
}
code와 more_info는 필드 자체가 없는 경우도 있다.
{
"meta": {
"code": 400,
"errorDetail": "Missing access credentials. See https://developer.foursquare.com/docs/oauth.html for details.",
"errorType": "invalid_auth"
},
"response": {}
}
Foursquare의 특징은 일반적인 응답과 에러 응답의 형식의 차이가 없고, 에러가 발생한 뒤에 응답의 meta 키에 에러가 들어가는 것이다.
{
"code": 96,
"message": "Invalid signature",
"stat": "fail"
}
Flickr는 심플한 형식이지만 stat이 있는 점이 특징이다.
{
"errorCode": 0,
"message": "Unknown authentication scheme",
"requestId": "PFB5T8NVLO",
"status": 401,
"timestamp": 1432283172233
}
Linkein의 에러 응답은 요청 ID와 요청한 타임 스탬프가 있다는 점이다. 만약 개발자로 부터 문의가 있는 경우에 커뮤니케이션 하기 쉬울 것 같다. 단지, 요청 ID 등은 헤더에 있는 편이 좋지 않을까 생각한다.
[
{
"error": {
"type": 2,
"address": "/",
"description": "body contains invalid json"
}
}
]
{
"message": "Not found",
"type": "not_found"
}
궁금했던 것인데 잘 정리해주셔서 감사합니다