JSON은 데이터를 전송하는 데 유용한 방법입니다. 이제 Couchbase 5.0의 CURL 업데이트 덕분에 N1QL이 이를 쿼리할 수 있습니다. 이를 위해 다양한 엔드포인트에 연결하는 방법을 알아보세요.
N1QL 에는 특정 작업을 수행할 수 있는 많은 기능이 있습니다. 새로운 Couchbase 5.0 DP에 추가된 기능 중 하나는 CURL입니다.
CURL을 사용하면 N1QL을 사용하여 외부 JSON 엔드포인트, 즉 JSON 형식으로 결과 및 데이터를 반환하는 Rest API와 상호 작용할 수 있습니다. 이 기능을 통해 N1QL은 언어에 내장된 보수적인 curl 기능 세트를 사용할 수 있습니다. 상호 작용은 주로 http 및 https 프로토콜을 사용하여 서버와의 데이터 전송으로 이루어집니다. 간단히 말해, N1QL의 CURL 함수는 사용자에게 표준 curl 기능의 하위 집합(https://curl.haxx.se/docs/manpage.html)를 쿼리 언어 내에서 사용할 수 있습니다.
다른 서버(예: 구글 맵, 야후 파이낸스 등)에서 데이터를 검색하기 위해 CURL 함수를 사용하여 GET 또는 HTTP POST 요청을 발행할 수 있습니다. 아래 다이어그램에서 확인할 수 있습니다.
기능 정의
CURL(URL, [옵션])
첫 번째 인수는 URL로, JSON 엔드포인트를 가리키는 모든 URL을 나타냅니다. http:// 또는 https:// 프로토콜을 사용하는 URL만 지원됩니다. 리디렉션은 비활성화됩니다.
CURL() 함수에 대한 입력 인수는 정적 값과 평가할 수 있는 N1QL 표현식이 될 수 있습니다.
이 글의 뒷부분에서 구글 지오코드 API, 야후 파이낸스 API, 카우치베이스 전체 텍스트 검색 및 깃허브 API에서 쿼리하는 예제를 살펴보겠습니다. 두 번째 인수는 옵션 목록입니다. 이것은 curl 옵션 목록과 해당 값을 포함하는 JSON 객체입니다.
저희는 모든 엔드포인트와 효과적으로 상호 작용할 수 있는 다양한 옵션을 지원합니다. 일반적으로 이러한 옵션은 보안 관련 옵션과 일반 옵션으로 분류할 수 있습니다. 지원되는 옵션의 표는 이 문서의 마지막에 나와 있습니다.
CURL의 보안 기능/개선 사항
보안 취약점을 방지하고 이와 관련된 위험을 제어하고 최소화하기 위해 CURL 기능이 추가됨에 따라 여러 가지 보안 조치가 구현되었습니다.
N1QL의 CURL 기능으로 CA 인증서 사용하기
N1QL CURL 함수에서 사용하는 인증서는 클러스터 내의 모든 쿼리 노드에 n1qlcerts 디렉터리에 저장되어야 합니다. 사용자가 이 디렉터리를 만들어야 하는 위치는 카우치베이스 설치 위치에 따라 다릅니다. (OS에 따라 다릅니다). 다음은 기본 설치 위치를 가정하여 n1qlcerts 디렉터리가 생성된 위치를 보여줍니다.
Linux | /옵트/카우치베이스/변/라이브/카우치베이스/엔1qlcerts |
Mac OSX | /사용자/카우치베이스/라이브러리/응용 프로그램\ 지원/카우치베이스/var/lib/카우치베이스/n1qlcerts |
Windows | C:\프로그램 파일\카우치베이스\서버\변수\lib\카우치베이스\n1qlcerts |
기본 설치 위치가 아닌 경우, cbq-엔진이 실행되는 bin 디렉터리에서 상대 경로인 "../var/lib/couchbase/n1qlcerts 디렉토리"를 만들어야 합니다.
이 디렉터리는 모든 쿼리 노드에 대해 만들어야 합니다.
이 디렉터리가 생성되면 여기에 CURL에 사용할 인증서를 추가합니다. 이 인증서를 사용하려면 cacert 옵션을 사용하고 인증서 이름을 전달합니다.
예를 들어 n1qlcerts/user1.pem이 인증서 이름인 경우, cacert 옵션을 사용합니다.
"cacert":"user1.pem"
이름만 유효하고 경로는 유효하지 않으며 경로를 전달하면 오류가 발생합니다. 유효하지 않은 인증서 및 만료된 인증서의 경우 CURL()은 오류를 발생시킵니다.
참고: 클러스터 내의 각 쿼리 노드에 대해 n1qlcerts 디렉터리와 그 내용을 복제해야 합니다.
사용자 지정 헤더 및 사용자 에이전트
CURL()은 클러스터 내의 쿼리 노드에서 실행됩니다. 이렇게 하면 함수가 쿼리 서비스를 통해 액세스할 수 있는 모든 REST 엔드포인트에 액세스할 수 있습니다(함수가 실행되는 곳이기 때문에). 이러한 안전하지 않은 엔드포인트에 대한 액세스를 방지하기 위해 사용자가 변경할 수 없는 사용자 정의 헤더가 N1QL curl 함수를 사용하여 전송되는 모든 요청에 추가됩니다. 이 헤더의 형식은 "X-N1QL-User-Agent: couchbase/n1ql/1.7.0-N1QL"입니다.
사용자 에이전트도 항상 기본적으로 설정되어 있습니다. 사용자 에이전트는 -user-agent 옵션을 사용하여 재설정할 수 있습니다. 기본적으로 설정된 값은 "couchbase/n1ql/1.7.0-N1QL"입니다.
이 두 값은 내부 및 외부 엔드포인트가 모두 헤더/사용자 에이전트를 확인하고 코드에서 액세스를 허용하지 않고 해당 기능에 대한 액세스를 거부할 수 있도록 설계되었습니다. 그러나 이를 사용할 때 한 가지 주의할 점은 이 헤더를 확인하지 않는 소프트웨어와 로컬에 설치된 소프트웨어의 기존 버전(카우치베이스 및 카우치베이스가 아닌 소프트웨어 모두)을 여전히 보호할 수 없다는 것입니다. 이러한 경우를 위해 컬 화이트리스트 기능이 추가되었습니다(아래 참조).
화이트리스트를 생성하여 CURL 액세스를 제한합니다.
화이트리스트는 CURL() 함수가 액세스할 수 있는 허용된 REST 엔드포인트와 URL을 나열하는 JSON 문서입니다. URL 자체는 접두사가 일치해야 합니다. 화이트리스트 문서는 n1qlcerts 디렉터리(위치는 위 참조) 내에 만들어지며, 이름은 curl_whitelist.json입니다(이 이름은 고정되어 있으며 사용자가 변경할 수 없음). 관리자(또는 카우치베이스가 설치된 컴퓨터에 대한 액세스 권한이 있는 사용자)가 이 파일(curl_whitelist.json)을 만들어야 합니다.
화이트리스트가 설정되어 있지 않거나(..../n1qlcerts/curl_whitelist.json이 존재하지 않음) 존재하지만 비어 있는 경우 CURL 함수를 사용할 수 없습니다.
모든 화이트리스트에는 다음 필드가 있어야 합니다.
필드 | 유형 | 설명 | 기본값 |
all_access | 부울 | 이렇게 하면 사용자가 모든 URL에 액세스할 수 있는지 아니면 allowed_urls 배열에 지정된 URL에만 액세스할 수 있는지 결정됩니다. | false |
allowed_urls | 배열 | 허용하려는 URL의 접두사 목록입니다. | 빈 |
disallowed_urls | 배열 | 어떤 경우에도 제한되는 URL의 접두사 목록 | 빈 |
all_access 필드가 거짓이면 CURL 함수에 대한 사용이 완전히 제한됩니다. N1QL의 모든 엔드포인트에서 CURL()을 사용하려면 관리자가 허용된_urls 및 허용되지 않은_urls를 적절히 설정해야 합니다. 모든 URL에 대한 액세스를 허용하려면 all_access를 true로 설정하면 됩니다. 이렇게 하면 기본적으로 전체 CURL 액세스 권한이 부여됩니다.
예를 들어 모든 Google 지도 API 엔드포인트에 대한 액세스는 허용하되 다른 모든 엔드포인트에 대한 액세스는 제한하고 싶다고 가정해 보겠습니다. 다음은 화이트리스트의 내용입니다.
Curl_whitelist.json
1 2 3 4 |
{ "all_access":false, "allowed_urls":["https://maps.googleapis.com"] } |
접두사가 앞에 붙은 CURL()의 모든 URL https://maps.googleapis.com/ 가 허용됩니다.
참고: 화이트리스트는 클러스터 내의 각 쿼리 노드에 대해 복제되어야 합니다.
CURL 함수에 대한 역할 기반 액세스
여기서 언급할 만한 중요한 점은 CURL이 임의로 호출될 수 없도록 설계되었다는 것입니다. UPDATE 문을 사용하여 외부 소스에서 데이터가 주입되는 것을 방지하기 위해 새로운 역할인 QUERY_EXTERNAL_ACCESS가 추가되었습니다. 이 역할이 할당된 사용자만 CURL 함수에 액세스할 수 있습니다. 기본적으로 이 역할 멤버십은 비어 있습니다. CURL 함수는 FULL_ADMIN 또는 FULL_ADMIN에 의해 QUERY_EXTERNAL_ACCESS 역할이 부여된 사용자만 액세스할 수 있습니다. 역할 기반 액세스 제어를 지원하지 않는 이전 버전의 카우치베이스의 경우 비밀번호로 보호된 버킷을 사용할 수 있습니다. 또한 CURL() 기능의 경우 내부적으로 특정 SSL 암호 세트(MEDIUM 또는 HIGH)가 지원됩니다. 이는 COUCHBASE_SSL_CIPHER_LIST에 따라 달라집니다.
CURL()의 결과 크기 제한하기
CURL() 함수를 사용할 때 중요한 문제는 사용자가 64MB가 넘는 매우 긴 파일을 만들어서 읽으려고 할 때입니다. 데이터가 메모리에 로드되므로 결과 크기가 제한되지 않으면 쿼리 서비스가 중단될 수 있습니다. 이러한 가능성 때문에 CURL()이 반환할 수 있는 데이터의 최대 결과 크기는 64MB(67,108,864바이트)입니다. 사용자는 CURL 결과의 메모리 양을 제한하기 위해 결과-캡 옵션의 최소(기본)값은 20MB(2097120바이트)입니다.
예를 들어 쿼리에서 결과-캡을 20MB로 설정하는 경우 - "result-cap":20971520 - 이보다 큰 크기의 응답은 오류를 반환합니다.
다양한 엔드포인트와의 상호 작용
N1QL의 CURL 함수를 사용하여 다양한 엔드포인트를 쿼리하는 방법을 살펴보겠습니다.
Google 지도 지오코딩 API
Google 지도의 지오코딩 API를 사용하면 HTTP 요청을 사용하여 정적 주소를 좌표로 변환하거나 그 반대로 변환할 수 있습니다. (자세한 내용은 https://developers.google.com/maps/documentation/geocoding/intro )
Google 개발자 API 키를 사용하여 스페인의 산타크루즈를 검색하고 싶다고 가정해 보겠습니다. 이를 위해 다음 쿼리를 사용할 수 있습니다:
컬 요청
1 |
curl https://maps.googleapis.com/maps/api/geocode/json?address=santa+cruz&components=country:ES&key= |
해당 쿼리
1 |
선택 CURL("https://maps.googleapis.com/maps/api/geocode/json", {"get":true,"데이터":"주소=santa+cruz&컴포넌트=국가:ES&키="}) GEO; |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 |
"결과": [ { "GEO": { "결과": [ { "주소_구성요소": [ { "long_name": "산타 크루즈 데 테네리페", "short_name": "산타 크루즈 데 테네리페", "types": [ "지역", "정치적" ] }, { "long_name": "산타 크루즈 데 테네리페", "short_name": "TF", "types": [ "관리 영역_레벨_2", "정치적" ] }, { "long_name": "카나리아 제도", "short_name": "CN", "types": [ "관리 영역 수준_1", "정치적" ] }, { "long_name": "스페인", "short_name": "ES", "types": [ "country", "정치적" ] } ], "형식화된_주소": "산타 크루즈 데 테네리페, 스페인", "지오메트리": { "bounds": { "북동쪽": { "lat": 28.487616, "lng": -16.2356646 }, "남서쪽": { "lat": 28.4280248, "lng": -16.3370045 } }, "위치": { "lat": 28.4636296, "lng": -16.2518467 }, "위치 유형": "APPROXIMATE", "뷰포트": { "북동쪽": { "lat": 28.487616, "lng": -16.2356646 }, "남서쪽": { "lat": 28.4280248, "lng": -16.3370045 } } }, "place_id": "ChIJcUElzOzMQQwRLuV30nMUEUM", "types": [ "지역", "정치적" ] } ], "status": "OK" } } ] |
이 쿼리는 주소인 Santa Cruz, ES의 주소 및 지리적 위치 경계를 검색합니다. Google Maps 지오코딩 REST API의 주소, 구성 요소 및 주요 매개변수를 사용합니다. '데이터' 옵션은 HTTP POST 데이터를 나타내는 curl 데이터 옵션을 나타냅니다. 그러나 이것은 가져오기 요청이므로 "get" 옵션을 true로 설정합니다. 데이터 옵션 내의 모든 REST 매개변수에 값을 제공할 수 있습니다.
이제 하프문 베이를 검색해 보겠습니다.
1 |
선택 CURL("https://maps.googleapis.com/maps/api/geocode/json", {"데이터":"주소=하프문+베이", "get":true}) GEO; |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 |
"결과": [ { "GEO": { "결과": [ { "주소_구성요소": [ { "long_name": "하프문 베이", "short_name": "하프문 베이", "types": [ "지역", "정치적" ] }, { "long_name": "산 마테오 카운티", "short_name": "산 마테오 카운티", "types": [ "관리 영역_레벨_2", "정치적" ] }, { "long_name": "캘리포니아", "short_name": "CA", "types": [ "관리 영역 수준_1", "정치적" ] }, { "long_name": "미국", "short_name": "US", "types": [ "country", "정치적" ] } ], "형식화된_주소": "하프문베이, 캘리포니아, 미국", "지오메트리": { "bounds": { "북동쪽": { "lat": 37.5226389, "lng": -122.4165183 }, "남서쪽": { "lat": 37.4249286, "lng": -122.4778879 } }, "위치": { "lat": 37.4635519, "lng": -122.4285862 }, "위치 유형": "APPROXIMATE", "뷰포트": { "북동쪽": { "lat": 37.5226389, "lng": -122.4165183 }, "남서쪽": { "lat": 37.4249286, "lng": -122.4778879 } } }, "place_id": "ChIJC8sZCqULj4ARVJvnNcic_V4", "types": [ "지역", "정치적" ] } ], "status": "OK" } } ] |
야후 파이낸스 API
야후 파이낸스 API를 사용하면 야후 쿼리 언어(YQL)를 사용하여 주식 시세를 가져올 수 있습니다( http://meumobi.github.io/stocks%20apis/2016/03/13/get-realtime-stock-quotes-yahoo-finance-api.html ). 다음은 Hortonworks Inc(HDP)의 주식에 액세스하는 YQL SELECT 문입니다.
1 |
선택 * 에서 야후.금융.따옴표 어디 기호 in ("HDP") |
결과를 JSON으로 가져오려면 다음 URL을 사용할 수 있습니다:
컬 요청
1 |
curl https://query.yahooapis.com/v1/public/yql --data 'q=select%20*%20from%20yahoo.finance.quotes%20where%20symbol%20in%20(%22HDP%22)&format=json&diagnostics=true&env=store%3A%2F%2Fdatatables.org%2Falltableswithkeys&callback=' |
해당 쿼리
1 2 3 |
선택 temp.쿼리.결과 에서 CURL("https://query.yahooapis.com/v1/public/yql", {"데이터":"q=select%20*%20from%20yahoo.finance.quotes%20where%20symbol%20in%20(%22HDP%22)&format=json&diagnostics=true&env=store%3A%2F%2Fdatatables.org%2Falltableswithkeys&callback="})temp; |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 |
"결과": [ { "결과": { "quote": { "애프터아워체인지실시간": null, "연간 이득": null, "물어보기": "16.950", "AskRealtime": null, "평균 일일 거래량": "952135", "Bid": "16.940", "BidRealtime": null, "BookValue": "-0.654", "변경": "+0.075", "50일 이동 평균 변경": "0.377", "ChangeFrom2백일이동평균": "3.625", "ChangeFromYearHigh": "-0.755", "ChangeFromYearLow": "10.525", "ChangePercentRealtime": null, "ChangeRealtime": null, "변경_퍼센트변경": "+0.075 - +0.445%", "ChangeinPercent": "+0.445%", "커미션": null, "통화": "USD", "DaysHigh": "17.010", "DaysLow": "16.780", "DaysRange": "16.780 - 17.010", "DaysRangeRealtime": null, "DaysValueChange": null, "DaysValueChangeRealtime": null, "배당금 지급일": null, "DividendShare": null, "DividendYield": null, "EBITDA": "-223.00M", "EPSEstimateCurrentYear": "-1.720", "EPSEstimateNextQuarter": "-0.380", "EPSEstimateNextYear": "-1.190", "EarningsShare": "-3.737", "유효하지 않은 기호 변경으로 반환된 오류 표시": null, "ExDividendDate": null, "50일 이동 평균": "16.568", "HighLimit": null, "홀딩스게인": null, "홀딩스게인퍼센트": null, "홀딩스게인퍼센트실시간": null, "홀딩스게인실시간": null, "홀딩스 가치": null, "홀딩스 가치 실시간": null, "LastTradeDate": "10/5/2017", "LastTradePriceOnly": "16.945", "LastTradeRealtimeWithTime": null, "LastTradeTime": "12:50pm", "LastTradeWithTime": "\uc624\ud6c4 12\uc2dc 50\ubd84 - <b>16.945<\/b>", "LowLimit": null, "MarketCapRealtime": null, "시가총액": "700.96M", "MoreInfo": null, "이름": "Hortonworks, Inc.", "메모": null, "OneyrTargetPrice": "18.930", "Open": "17.010", "OrderBookRealtime": null, "PEGRatio": "-0.400", "PERatio": null, "PERatioRealtime": null, "PercebtChangeFromYearHigh": "-4.266%", "퍼센트 변경": "+0.445%", "50일 이동 평균으로부터의 퍼센트 변화": "+2.275%", "2백일 이동 평균으로부터의 퍼센트 변화": "+27.214%", "PercentChangeFromYearLow": "+163.941%", "이전닫기": "16.870", "PriceBook": null, "PriceEPSEstimateCurrentYear": null, "PriceEPSEstimateNextYear": null, "PricePaid": null, "PriceSales": "3.212", "SharesOwned": null, "ShortRatio": "3.640", "StockExchange": "NMS", "심볼": "HDP", "TickerTrend": null, "TradeDate": null, "2백일 이동 평균": "13.320", "볼륨": "217430", "YearHigh": "17.700", "YearLow": "6.420", "YearRange": "6.420 - 17.700", "심볼": "HDP" } } } ] |
이 쿼리의 경우 데이터 옵션의 값에는 Yahoo REST 매개 변수인 q(YQL 쿼리의 경우), 형식(JSON으로 데이터를 반환하기 위한) 및 기타 몇 가지 매개 변수가 포함되어 있습니다.
카우치베이스 전체 텍스트 검색
Couchbase의 전체 텍스트 검색을 사용하면 Couchbase에 저장된 데이터에 퍼지 검색을 적용할 수 있습니다. 자세한 내용은 다음을 참조하세요. https://www.couchbase.com/blog/couchbase-4.5-developer-preview-couchbase-fts/.
Couchbase의 맥주 샘플 버킷에 beer라는 FTS 인덱스를 생성한다고 가정해 보겠습니다. 이제 이 인덱스를 사용하여 N1QL의 CURL 함수를 사용하여 맥주 종류 페일 에일을 검색할 수 있습니다. FTS는 현재 GET 대신 HTTP POST를 허용한다는 점에 유의해야 합니다. POST 요청 방법을 명시적으로 지정하려면 요청 옵션을 사용하세요.
컬 요청
1 |
curl -u 맥주-샘플:통과 -XPOST -H "콘텐츠 유형: 애플리케이션/json" http://127.0.0.1:8094/api/index/beers/query -d '{ "explain": true, "fields": ["*"],"highlight": {},"query": {"query": "페일 에일"}}' |
해당 쿼리
1 2 3 4 5 |
선택 결과.총 조회수, 배열_길이(결과.조회수) 페이지당 조회수 FROM CURL("http://localhost:8094/api/index/beers/query", {"요청":"POST","header":"콘텐츠 유형: 애플리케이션/json", "데이터":'{"설명":false,"필드": ["*"],"highlight": {},"query": {"query": "페일 에일"}}', "user":"관리자:비밀번호"}) 결과; |
1 2 3 4 5 6 |
"결과": [ { "조회수_당_페이지": 10, "total_hits": 3815 } ] |
이 쿼리에는 여러 옵션이 제공됩니다. 헤더 옵션을 사용하면 사용자 지정 헤더를 서버에 전달할 수 있습니다. Content-Type : application/json은 데이터가 JSON 형식으로 제공됨을 서버에 알려줍니다. Couchbase에 비밀번호로 보호된 버킷이 있는 경우 쿼리와 함께 해당 자격 증명을 전달해야 합니다. 사용자 옵션은 콜론으로 구분된 사용자 이름과 비밀번호를 전달하는 데 사용할 수 있습니다. 요청 옵션은 POST 요청 방법을 사용하도록 지정합니다.
위의 검색에서 반환된 맥주 샘플의 문서만 검색하려면 다음과 같이 N1QL JOIN 쿼리를 작성하면 됩니다.
1 2 3 4 5 6 7 8 9 |
선택 배열 x.id 에 대한 x in b1.결과.조회수 END as 조회수, b1.결과.총 조회수 as 합계, 배열_길이(b1.결과.조회수), b FROM (선택 CURL("http://localhost:8094/api/index/beers/query", {"요청":"POST","header":"콘텐츠 유형: 애플리케이션/json", "데이터":'{"설명":false,"필드": ["*"],"highlight": {},"query": {"query": "페일 에일"}}', "user":"관리자:비밀번호"}) 결과) b1 INNER JOIN `맥주-샘플` b 켜기 키 b1.결과.조회수[*].id LIMIT 1; |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 |
"결과": [ { "$1": 10, "b": { "abv": 5.4, "brewery_id": "stone_brewing_co", "category": "북미 에일", "설명": "우리의 대표 에일인 스톤 페일 에일은 클래식한 영국식 페일 에일 스타일을 남부 캘리포니아에서 재해석한 맥주입니다. 짙은 호박색을 띠는 스톤 페일 에일은 견고하고 풍미가 풍부합니다. 섬세한 홉 향이 풍부한 몰트 풍미와 조화를 이룹니다. 독특한 풍미를 즐기는 분들을 위한 에일 맥주입니다. 스톤 페일 에일은 단독으로 마셔도 좋고, 개성 있는 맥주가 필요한 음식과 함께 마셔도 좋습니다.", "ibu": 0, "name": "스톤 페일 에일", "srm": 0, "style": "아메리칸 스타일 페일 에일", "type": "맥주", "upc": 0, "업데이트됨": "2010-07-22 20:00:20" }, "조회수": [ "스톤브루잉_코스톤_팔레일", "플라잉독_브루어리-클래식_팔레일", "야드_양조장_필라델피아_팔레일", "bell_s_brewery_inc-pale_ale", "시에라_네바다_브루잉_코-시에라_네바다_페일_에일", "쿠퍼_스케이브_에일_컴퍼니-쿠퍼_스케이브_페일_에일", "appalachian_brewing_company-hoppy_trails_india_pale_ale", "쿠퍼타운_브루잉_컴퍼니-백야드_인도_페일_에일", "모골론_양조_회사-미신_창백한_알레", "트로에그_브루잉-트로에그_팔레일" ], "total": 3815 } ] |
이렇게 하면 페일 에일을 검색하는 FTS 쿼리가 반환한 문서의 ID와 함께 맥주 샘플의 해당 문서에서 총 조회수 및 모든 세부 정보를 검색할 수 있습니다.
Github API
Github의 API는 결과 값의 JSON 배열 형태로 여러 결과를 반환한다는 점에서 이전 API와 약간 다릅니다. 이는 여러 개의 문서로 취급될 수 있으며, Github API 문서에서 https://developer.github.com/v3/ 를 클릭하여 조회할 수 있는 항목에 대해 자세히 알아보세요.
Github 계정에 연결된 모든 리포지토리를 찾고 싶다고 가정해 보겠습니다. 다음 쿼리는 이를 수행합니다.
컬 요청
1 |
curl -H "사용자 에이전트: ikandaswamy" https://api.github.com/users/ikandaswamy/repos |
해당 쿼리
1 |
선택 RAW 목록 FROM CURL("https://api.github.com/users/ikandaswamy/repos")목록 LIMIT 1; |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 |
"결과": [ { "archive_url": "https://api.github.com/repos/ikandaswamy/ds-algo/{아카이브_포맷}{/ref}", "양수인_URL": "https://api.github.com/repos/ikandaswamy/ds-algo/assignees{/user}", "blobs_url": "https://api.github.com/repos/ikandaswamy/ds-algo/git/blobs{/sha}", "브랜치_URL": "https://api.github.com/repos/ikandaswamy/ds-algo/branches{/branch}", "clone_url": "https://github.com/ikandaswamy/ds-algo.git", "collaborators_url": "https://api.github.com/repos/ikandaswamy/ds-algo/collaborators{/collaborator}", "comments_url": "https://api.github.com/repos/ikandaswamy/ds-algo/comments{/number}", "commits_url": "https://api.github.com/repos/ikandaswamy/ds-algo/commits{/sha}", "compare_url": "https://api.github.com/repos/ikandaswamy/ds-algo/compare/{베이스}...{헤드}", "contents_url": "https://api.github.com/repos/ikandaswamy/ds-algo/contents/{+path}", "기여자_URL": "https://api.github.com/repos/ikandaswamy/ds-algo/contributors", "created_at": "2017-09-07T22:42:03Z", "default_branch": "master", "배포_URL": "https://api.github.com/repos/ikandaswamy/ds-algo/deployments", "설명": "데이터 구조와 알고리즘을 다시 배우면서 다양하고 재미있는 문제를 구현하는 데 사용하세요.", "downloads_url": "https://api.github.com/repos/ikandaswamy/ds-algo/downloads", "events_url": "https://api.github.com/repos/ikandaswamy/ds-algo/events", "포크": false, "포크": 0, "포크_수": 0, "forks_url": "https://api.github.com/repos/ikandaswamy/ds-algo/forks", "full_name": "ikandaswamy/ds-algo", "git_commits_url": "https://api.github.com/repos/ikandaswamy/ds-algo/git/commits{/sha}", "git_refs_url": "https://api.github.com/repos/ikandaswamy/ds-algo/git/refs{/sha}", "git_tags_url": "https://api.github.com/repos/ikandaswamy/ds-algo/git/tags{/sha}", "git_url": "git://github.com/ikandaswamy/ds-algo.git", "has_downloads": true, "has_issues": true, "has_pages": false, "has_projects": true, "has_wiki": true, "홈페이지": null, "hooks_url": "https://api.github.com/repos/ikandaswamy/ds-algo/hooks", "html_url": "https://github.com/ikandaswamy/ds-algo", "id": 102792479, "이슈_댓글_URL": "https://api.github.com/repos/ikandaswamy/ds-algo/issues/comments{/number}", "이슈_이벤트_URL": "https://api.github.com/repos/ikandaswamy/ds-algo/issues/events{/number}", "issues_url": "https://api.github.com/repos/ikandaswamy/ds-algo/issues{/number}", "keys_url": "https://api.github.com/repos/ikandaswamy/ds-algo/keys{/key_id}", "labels_url": "https://api.github.com/repos/ikandaswamy/ds-algo/labels{/name}", "언어": null, "languages_url": "https://api.github.com/repos/ikandaswamy/ds-algo/languages", "merges_url": "https://api.github.com/repos/ikandaswamy/ds-algo/merges", "milestones_url": "https://api.github.com/repos/ikandaswamy/ds-algo/milestones{/number}", "mirror_url": null, "name": "ds-algo", "알림_URL": "https://api.github.com/repos/ikandaswamy/ds-algo/notifications{?since,all,participating}", "open_issues": 0, "open_issues_count": 0, "소유자": { "avatar_url": "https://avatars1.githubusercontent.com/u/9203396?v=4", "events_url": "https://api.github.com/users/ikandaswamy/events{/privacy}", "팔로워_URL": "https://api.github.com/users/ikandaswamy/followers", "following_url": "https://api.github.com/users/ikandaswamy/following{/다른_사용자}", "gists_url": "https://api.github.com/users/ikandaswamy/gists{/gist_id}", "gravatar_id": "", "html_url": "https://github.com/ikandaswamy", "id": 9203396, "로그인": "ikandaswamy", "organizations_url": "https://api.github.com/users/ikandaswamy/orgs", "받은_이벤트_URL": "https://api.github.com/users/ikandaswamy/received_events", "repos_url": "https://api.github.com/users/ikandaswamy/repos", "사이트_관리자": false, "별표_URL": "https://api.github.com/users/ikandaswamy/starred{/소유자}{/레포}", "구독_URL": "https://api.github.com/users/ikandaswamy/subscriptions", "type": "사용자", "url": "https://api.github.com/users/ikandaswamy" }, "private": false, "pulls_url": "https://api.github.com/repos/ikandaswamy/ds-algo/pulls{/number}", "pushed_at": "2017-09-07T22:42:04Z", "releases_url": "https://api.github.com/repos/ikandaswamy/ds-algo/releases{/ID}", "size": 0, "ssh_url": "git@github.com:ikandaswamy/ds-algo.git", "스타게이저_수": 0, "스타게이저_URL": "https://api.github.com/repos/ikandaswamy/ds-algo/stargazers", "statuses_url": "https://api.github.com/repos/ikandaswamy/ds-algo/statuses/{sha}", "구독자_URL": "https://api.github.com/repos/ikandaswamy/ds-algo/subscribers", "구독_URL": "https://api.github.com/repos/ikandaswamy/ds-algo/subscription", "svn_url": "https://github.com/ikandaswamy/ds-algo", "tags_url": "https://api.github.com/repos/ikandaswamy/ds-algo/tags", "teams_url": "https://api.github.com/repos/ikandaswamy/ds-algo/teams", "trees_url": "https://api.github.com/repos/ikandaswamy/ds-algo/git/trees{/sha}", "updated_at": "2017-09-07T22:42:03Z", "url": "https://api.github.com/repos/ikandaswamy/ds-algo", "watchers": 0, "watchers_count": 0 } ] |
계정에 리포지토리가 3개 있는 경우 쿼리는 3개의 결과를 반환합니다(여기서는 제한 1을 추가했습니다). RAW 키워드는 래퍼 객체 없이 쿼리가 반환하는 문서 배열을 반환하는 데 사용됩니다. 한 가지 눈에 띄는 점은 헤더 옵션에 사용자 에이전트와 github 사용자 이름이 포함되어 있다는 것입니다. 이 옵션은 이제 모든 Github API 요청에 필수입니다.
이제 이 목록에서 각 리포지토리의 복제 URL이 무엇인지 알고 싶다고 가정해 보겠습니다. 다음 쿼리는 이를 수행합니다.
1 2 3 4 |
선택 clone_url FROM (선택 RAW 목록 FROM CURL("https://api.github.com/users/ikandaswamy/repos", {"header":"사용자 에이전트: ikandaswamy"}) 목록) s; |
1 2 3 4 5 6 7 8 9 10 11 |
"결과": [ { "clone_url": "https://github.com/ikandaswamy/ds-algo.git" }, { "clone_url": "https://github.com/ikandaswamy/github-cheat-sheet.git" }, { "clone_url": "https://github.com/ikandaswamy/jsapp.git" } ] |
요약
위의 예제에서 볼 수 있듯이, 이제 N1QL 사용자는 CURL 함수를 사용하여 결과를 JSON 형식으로 반환하는 모든 외부 API와 상호 작용할 수 있습니다. 이는 많은 가능성을 열어줍니다. 예를 들어 Couchbase에 여러 호텔에 해당하는 데이터가 포함되어 있는 경우 Google 지도 API를 사용하여 각 호텔의 인근 위치를 찾을 수 있습니다.
CURL()을 추가하여 안전한 환경을 만들기 위해 여러 가지 보안 강화 기능이 추가되었습니다. 다음은 간단한 목록입니다.
- CURL은 클러스터 내의 쿼리 노드에서 실행됩니다.
- CURL 기능은 기본적으로 비활성화되어 있습니다.
- CURL은 HTTP와 HTTPS만 지원합니다. 다른 모든 프로토콜은 비활성화됩니다.
- URL 리디렉션은 허용되지 않습니다.
- N1QL CURL의 사용자 지정 헤더는 "X-N1QL-User-Agent: couchbase/n1ql/1.7.0-N1QL"입니다.
- 사용자 에이전트는 "couchbase/n1ql/1.7.0-N1QL"입니다.
- 결과 제한을 사용하여 CURL 결과의 메모리 양을 제한합니다. 최소 결과 제한은 20MB, 최대 결과 제한은 64MB입니다.
- FULL_ADMIN 역할은 CURL에 대한 액세스를 허용합니다. 쿼리_외부_액세스 역할은 전체 관리자가 사용자에게 할당할 수 있습니다. 이렇게 하면 사용자가 CURL 기능을 사용할 수 있습니다.
- 인증서는 클러스터 내의 각 쿼리 노드인 로컬 머신에 저장해야 합니다. ..../Couchbase/var/lib/couchbase/n1qlcerts를 사용하여 인증서를 저장하고, 사용할 인증서의 '이름'을 전달하려면 cacert를 사용합니다. 이름만 유효하며 경로는 유효하지 않습니다. (경로를 전달하면 오류가 발생합니다.)
- 유효하지 않거나 만료된 인증서가 있는 경우 CURL에서 오류가 발생합니다.
- 사용자는 엔드포인트를 '화이트리스트'로 지정할 수 있습니다.
CURL의 N1QL 구현은 golang libcurl API를 사용합니다. https://github.com/andelf/go-curl
사용 가능한 옵션 목록
보안 옵션
옵션 | 설명 | 값 |
사용자 | 서버 사용자 및 비밀번호
비밀번호가 비어 있으면 빈 비밀번호 문자열로 취급됩니다. |
사용자명[:비밀번호] |
기본 | HTTP 기본 인증 사용 | 부울(참/거짓) |
안전하지 않음 | 인증서 없이 SSL 사이트에 연결 허용(H) | 부울(참/거짓) |
anyauth | curl을 사용하여 스스로 인증 방법을 알아내고 가장 안전한 방법을 사용합니다. | 부울(참/거짓) |
cacert | CA 서명 인증서 파일 이름 지정
인증서는 클러스터 내의 각 쿼리 노드인 로컬 머신에 저장해야 합니다. /Couchbase/var/lib/couchbase/n1qlcerts에 인증서를 저장합니다. 이것은 사용자에게 표시되지 않습니다. 파일 이름에 경로를 포함할 수 없습니다. n1qlcerts 디렉터리의 기존 콘텐츠와 일치하지 않으면 함수가 오류를 발생시킵니다. 만료된 인증서 및 유효하지 않은 인증서의 경우 오류가 발생합니다. |
파일 이름(예: aws의 경우 인증서, pem 파일) |
결과-캡 | CURL 작업 결과를 저장하는 버퍼의 용량 설정 | MB 수입니다. (최소 20MB) |
기타 전송 관련 옵션
옵션 | 설명 | 가치 |
get, G | CURL 요청 받기 | 부울(참/거짓) |
X, 요청 | 요청 방법을 설정합니다. GET 또는 POST만 허용하며 대소문자를 구분합니다.
다른 모든 경우에는 오류가 발생합니다. |
{"request":"POST"} |
연결 시간 초과 | 연결에 허용되는 최대 시간입니다. 서버 연결 단계에 걸리는 최대 시간(초)을 포함해야 합니다. 이는 연결 단계를 제한할 뿐 연결 후에는 아무런 영향을 미치지 않습니다. 기본 설정 연결 시간 제한인 300초로 전환하려면 0으로 설정합니다.
플로트 값인 경우 정수 값으로 잘라냅니다. 숫자가 아닌 다른 모든 유형은 오류를 던집니다. |
초 |
최대 시간 | 전송 작업에 허용되는 최대 시간입니다.
기본 시간 제한은 0(0)으로, 전송 중에 시간 제한이 걸리지 않습니다. 플로트 값인 경우 정수 값으로 잘라냅니다. 숫자가 아닌 다른 모든 유형은 오류를 던집니다. |
초 |
데이터 | HTTP POST 데이터(H)
주어진 엔드포인트에 대한 나머지 모든 API 매개변수를 설정할 수 있습니다. |
문자열
또는 [...문자열,문자열....] |
헤더 | 사용자 지정 헤더 문자열을 서버에 전달(H) | 문자열
또는 [...문자열,문자열....] |
show-error | 오류 표시.
참이면 오류 발생 시 오류를 표시합니다. 거짓으로 오류를 억제하는 경우 |
부울(참/거짓) |
침묵 | 무음 모드(아무것도 출력하지 않음) | 부울(참/거짓) |
킵얼라이브 시간 | 낮은 수준의 TCP 연결을 위해 킵얼라이브 프로브 사이에 몇 초간 대기합니다. (HTTP 수준 킵얼라이브에는 영향을 주지 않음) | 초 |
사용자 에이전트 | 서버로 전송할 사용자 에이전트의 값입니다. | 문자열 |
데이터 URL 코드 | 데이터를 인코딩하고 서버로 전송합니다.
This is a test => this%20is%20a%20test |
문자열
또는 [...문자열,문자열....] |