요즘은 API에서 데이터를 주고받을 때 JSON을 사용하는 것이 대부분이기 때문에 어떤 시스템과 연동하든 JSON 결과를 받아서 사용하는 경우가 많은데 서버에서 JSON 응답을 이쁘게 포매팅해서 보내준다면 보기가 쉽지만 압축해서 보내준다면 어떤 필드나 데이터가 있는지 한눈에 파악해서 보기가 어렵다. 코드에서 파싱할 때는 상관없지만, 필드를 확인해서 코드를 작성해야 하거나 디버깅을 해야 하는 경우에는 JSON을 이쁘게 출력해서 보아야 하는 경우가 많이 있다.
HTTP 요청을 보내고 결과도 포매팅해주는 도구를 사용하는 때도 많지만 개발하다 보면 그렇게 되지 않을 때도 있으므로 전에는 JSONLint 사이트를 이용해서 포매팅해서 결과를 확인했다. JSONLint는 JSON 데이터의 유효성 검사를 해주는 사이트이지만 유효성 검사를 할 때 포매팅도 해주므로 그 결과를 에디터 등에 복사해서 보면서 결과를 확인했다. 웹사이트이므로 어디서나 접속해서 사용할 수 있다는 장점도 있지만, 코드에서 사용하든 터미널에서 curl로 사용하든 결과를 복사해서 웹사이트를 열어서 복사한 뒤 결과를 사용해야 한다는 불편함이 존재했다.
예를 들어 https://api.stackexchange.com/2.2/search?site=stackoverflow&order=desc&sort=activity&intitle=http&filter=default 같은 API를 사용할 때 응답으로 받은 JSON 데이터가 어떤 구조로 되어 있고 어떤 값이 있는지 찾기가 쉽지 않다.
python 이용하기
이 응답을 복사해서 앞에서 얘기한 JSONLint에서 포매팅을 해도 되지만 자주 사용하는 일은 커맨드라인에서 사용하면 좀 더 편하다.(이건 사람마다 다를지도...) 이 요청을 curl을 사용해서 터미널에서 사용한다면 다음과 같이 사용할 수 있다.(--compressed
옵션은 stackexchange에서 응답을 바이너리로 주어서 넣은 옵션이다.)
$ curl 'https://api.stackexchange.com/2.2/search?site=stackoverflow&order=desc&sort=activity&intitle=http&filter=default' --compressed
{"items":[{"tags":["javascript","node.js","tizen-web-app"],"owner":{"reputation":1,"user_id":6056094,"user_type":"registered","profile_image":"https://www.gravatar.com/avatar/dfb9005186ad27236eab774ae88aaca9?s=128&d=identicon&r=PG&f=1","display_name":"Yahav Zamari","link":"http://stackoverflow.com/users/6056094/yahav-zamari"},"is_answered":false,"view_count":17,"answer_count":0,"score":0,"last_activity_date":1457865787,"creation_date":1457865787,"question_id":35969238,"link":"http://stackoverflow.com/questions/35969238/node-js-http-request-does-nothing-using-http-request","title":"node JS HTTP request does nothing using http request"},{"tags":["python","multithreading","concurrency","multiprocessing"],"owner":{"reputation":558,"user_id":991710,"user_type":"registered","accept_rate":81,"profile_image":"https://www.gravatar.com/avatar/f660a9ad68d31e30b2d7b153f7eb5bc5?s=128&d=identicon&r=PG","display_name":"user991710","link":"http://stackoverflow.com/users/991710/user991710"},"is_answered":tru
.......뒷부분은 생략
python -m json.tool
을 이용하면 JSON을 포매팅해서 사용할 수 있다.
$ curl 'https://api.stackexchange.com/2.2/search?site=stackoverflow&order=desc&sort=activity&intitle=http&filter=default' --compressed | python -m json.tool
{
"has_more": true,
"items": [
{
"answer_count": 0,
"creation_date": 1457865787,
"is_answered": false,
"last_activity_date": 1457865787,
"link": "http://stackoverflow.com/questions/35969238/node-js-http-request-does-nothing-using-http-request",
"owner": {
"display_name": "Yahav Zamari",
"link": "http://stackoverflow.com/users/6056094/yahav-zamari",
"profile_image": "https://www.gravatar.com/avatar/dfb9005186ad27236eab774ae88aaca9?s=128&d=identicon&r=PG&f=1",
"reputation": 1,
"user_id": 6056094,
"user_type": "registered"
},
"question_id": 35969238,
"score": 0,
"tags": [
"javascript",
"node.js",
"tizen-web-app"
],
"title": "node JS HTTP request does nothing using http request",
"view_count": 17
},
.......뒷부분은 생략
curl 'URL' | python -m json.tool
과 같이 CURL로 받은 응답을 파이프로 json.tool
에 연결하면 JSON을 포매팅해서 볼 수 있다. 터미널에서는 포매팅 되어도 결과를 확인하거나 검색해 보기 어려우므로 에디터에서 복사해서 보려면 ``curl 'URL' | python -m json.tool | pbcopy로
pbcopy`까지 연결하면 바로 클립보드에 복사되므로 에디터 등에 붙여넣어서 바로 볼 수 있다.
$ echo '{"foo": "lorem", "bar": "ipsum"}' | python -m json.tool
{
"bar": "ipsum",
"foo": "lorem"
}
웹 브라우저 등에서 JSON 결과를 받아서 이미 복사를 했다면 echo
명령어를 사용해서 위처럼 포매팅하는 것도 가능하다. 보통 python은 설치되어 있으므로 간단하게 JSON을 포매팅해서 볼 수 있는 유용한 방법이다.
jq
jq는 커맨드라인에서 JSON을 조작할 수 있는 도구이다. jq는 OS별로 바이너리를 제공하므로 자신의 OS에 맞는 버전을 설치하면 된다. OS X에서는 Homebrew를 이용해서 brew install jq
로 설치할 수 있다. 설치가 완료되면 터미널에서 jq
명령어를 사용할 수 있다.
$ jq --version
jq-1.5
이 jq
를 이용하면 앞에서 Python의 json.tool
을 쓴 것과 같게 JSON을 포매팅할 수 있다.
$ echo '{"foo": "lorem", "bar": "ipsum"}' | jq .
{
"foo": "lorem",
"bar": "ipsum"
}
curl
을 이용한다면 curl 'URL' | jq .
과 같이 사용할 수 있고 바로 복사를 하려면 curl 'URL' | jq . | pbcopy
와 같이 사용할 수 있다. jq
다음에 .
이 있음을 유의해야 한다. 단순히 포매팅만 한다면 명령어가 좀 더 간단한 것 외에는 json.tool
보다 좋은 점이 없지만 jq
는 좀 더 다양한 기능을 제공하고 있다.
다음과 같은 data.json
이 있다고 해보자.(앞의 stackexchange에서 받은 결과를 간단하게 만든 것이다.)
{
"has_more": true,
"items": [
{
"answer_count": 0,
"creation_date": 1457869825,
"is_answered": false,
"owner": {
"display_name": "trafalgar",
"reputation": 171
},
"question_id": 35969871,
"score": 0,
"tags": [
"cakephp",
"cakephp-2.0"
],
"title": "Accessing POST query parameters from HTTPS to HTTP",
"view_count": 2
},
{
"answer_count": 0,
"creation_date": 1457869139,
"is_answered": false,
"owner": {
"display_name": "Istv",
"reputation": 1
},
"question_id": 35969759,
"score": 0,
"tags": [
"android",
"get",
"httprequest"
],
"title": "Android Http response shows after second click only",
"view_count": 7
}
]
}
앞에서 jq .
과 같이 사용했을 때 .
는 JSON 문서의 루트를 의미한다. 그래서 JSON 데이터를 탐색하듯이 루트에서 시작해서 원하는 데이터를 탐색해 볼 수 있다.
$ cat data.json | jq .has_more
true
$ cat data.json | jq .items[0].owner.display_name
"trafalgar"
$ cat data.json | jq .items[1].tags
[
"android",
"get",
"httprequest"
]
$ cat data.json | jq .items[1].tags[]
"android"
"get"
"httprequest"
JSON 문서의 구조를 알고 있다면 복잡한 JSON 데이터에서 원하는 필드의 값을 바로 확인하는 것이 가능하다. .
으로 시작해서 약간 어색해 보이지만 탐색 방법은 흔히 사용하는 방식이라 약간만 사용해 보면 쉽게 사용할 수 있다.
$ cat data.json | jq \
> '.items[] | {answer: .answer_count, owner: .owner.display_name, date: .creation_date}'
{
"answer": 0,
"owner": "trafalgar",
"date": 1457869825
}
{
"answer": 0,
"owner": "Istv",
"date": 1457869139
}
위처럼 기존 JSON의 데이터를 이용해서 다른 형식의 JSON 문서를 만드는 것도 가능하다.(\
는 블로그에서 보기 편하게 줄을 나눈 것뿐이다.) 위에서는 item
에 있는 배열에서 원하는 값만 추출해서 새로운 형식의 JSON을 만든 것이다. 간단한 명령어는 그냥 사용해도 되지만 문법이 약간 복잡해 지면 jq에 전달하는 전체 파라미터를 따옴표('
)로 묶어 주어야 한다. jq의 파라미터 내에서도 파이프(|
)를 많이 사용하기 때문에 처음에는 좀 헷갈린다.
$ cat data.json | jq \
> '[.items[] | {answer: .answer_count, owner: .owner.display_name, date: .creation_date}]'
[
{
"answer": 0,
"owner": "trafalgar",
"date": 1457869825
},
{
"answer": 0,
"owner": "Istv",
"date": 1457869139
}
]
배열로 만들어야 한다면 전체를 []
로 감싸면 최종 결과도 배열로 나오게 된다.
커맨드라인에서 간단한 파서를 만든다면 필요할지도 모르지만 문서를 보면 아주 다양한 내장 함수를 포함하고 있어서 JSON 데이터를 원하는 대로 조작하고 탐색할 수 있다. 나는 아직 그 정도로 쓰고 있진 않고 API를 사용할 때 간단한 포매팅이나 원하는 값을 탐색하는 용도 정도로 쓰고 있다.
크롬 익스텐션 중에 Insight https://chrome.google.com/webstore/detail/sight/epmaefhielclhlnmjofcdapbeepkmggh 라는 걸 쓰고 있는데, xml이나 json 같은 소스를 포맷팅해서 보여주기 때문에 간단하게 브라우져에서 값을 확인할 때 사용하면 좋습니다. 커맨드 라인을 주로 사용한다면 jq도 좋아보이네요.
저도 전에는 이거 썼었는데 좀 돼서 정확히는 기억이 안나는데 언젠가 부터 잘 안쓰게 됐네요. 다른거랑 충돌해서 인지 테마가 좀 불편하게 느껴졌던것 같고 하다보면 브라우저외에서도 쓰게 되는경우가 종종 있더라구요.
문득 언제부터 Sight를 안썼지 하는 생각이 드는군요..
안녕하세요~~ 복잡한 json 을 object로 변환하는 법을 검색하다가 찾게 되었습니다.
저도 위에서 말씀하신것처럼 복잡한 api 에서 받은 json값을 object로 변환하는 방법을 찾고 있습니다. spring boot를 쓰고 있는데,
api 호출받은 json 값을 string 으로 변환하고 나서, 그 string을 다시 object로 변환한 다음에
특정값을 추출하고 싶은데, 어떤 방법이 있는지 여쭤보고 싶습니다
jackson을 쓰면 될까요?
제가 요즘은 자바를 안해서 정확하게는 모르는데 Jackson이나 gson을 많이 쓰는것 같습니다. 최근에 더 좋은게 있는지는 잘 모르겠습니다.
요즘은 API에서 데이터를 주고받을 때 JSON을 사용하는 것이 대부분이기 때문에 어떤 시스템과 연동하든 JSON 결과를 받아서 사용하는