일괄 처리 | Graph API concepts(Graph API 개념)
Azure AD Graph API를 사용하면 엔터티에 대한 작업을 일괄 처리하여 서버로의 왕복 횟수를 줄일 수 있습니다. 요청을 일괄 처리하면 네트워크 오버헤드가 감소하며 작업이 더 빨리 완료됩니다.
중요
Azure Active Directory 리소스에 액세스하려면 Azure AD Graph가 아닌 Microsoft Graph를 사용하는 것이 좋습니다.우리는 현재 Microsoft Graph 개발에 집중하고 있으며 앞으로 Azure AD Graph API에 대한 개선 작업은 계획이 없습니다.아직까지 Azure AD Graph API가 적합할 수 있는 시나리오는 매우 제한적입니다. 자세한 내용은 Office 개발자 센터의 Microsoft Graph 또는 Azure AD Graph 블로그 게시물을 참조하십시오.현재 Microsoft Graph에서는 일괄 처리가 지원되지 않습니다. 이 기능을 사용하려면 Azure AD Graph API를 사용해야 합니다.
OData 일괄 처리 요청에 대한 Graph API 지원
엔터티 일괄 처리의 의미 체계는 OData 3.0 일괄 처리 사양을 통해 지원됩니다. OData 사양에는 일괄 처리 요청에 대해 다음과 같은 개념들이 정의되어 있습니다.
- 쿼리는 단일 쿼리 또는 함수 호출입니다.
- 변경 집합은 하나 이상의 삽입/업데이트/삭제 작업, 작업 호출 또는 서비스 호출의 그룹입니다.
- 일괄 처리는 하나 이상의 변경 집합 및 쿼리 작업을 포함하는 작업들의 컨테이너입니다.
Graph API는 OData 사양에 정의된 기능의 하위 집합을 지원합니다.
- 단일 일괄 처리는 쿼리 및/또는 변경 집합을 총 5개까지 포함할 수 있습니다.
- 변경 집합은 수정된 소스 개체를 하나까지 포함할 수 있으며 링크 추가 및 링크 삭제 작업을 총 20개까지 포함할 수 있습니다. 변경 집합의 모든 작업은 단일 소스 엔터티에 있어야 합니다.
Graph API 일괄 처리 요청
다음 섹션에서는 일괄 처리 요청을 생성하고 일괄 처리 응답을 해석하는 방법에 대해 설명하며 이러한 각 방법에 대한 샘플을 제공합니다.
일괄 처리 요청 구문
일괄 처리 요청을 수행하려면 요청 URI에 $batch 옵션을 지정합니다. 예를 들면 다음과 같습니다.
https://graph.windows.net/contoso.onmicrosoft.com/$batch?api-version=1.6
일괄 처리 요청은 단일 POST 지시문을 사용해서 서버에 전달됩니다.
페이로드는 일괄 처리 및 일괄 처리를 구성하는 쿼리와 변경 집합이 포함된 다중 파트 MIME 메시지입니다. 페이로드에는 다음과 같은 두 가지 MIME 경계 유형이 포함됩니다.
- 일괄 처리의 각 쿼리 및/또는 변경 집합을 구분하는 일괄 처리 경계
- 변경 집합 내의 개별 작업을 구분하는 변경 집합 경계
변경 집합 내의 개별 요청은 작업 자체만 호출할 때 수행되는 요청과 동일합니다. 예를 들면 다음과 같습니다.
- 변경 집합의 각 작업에 대한 페이로드 형식(JSON 또는 ATOM)을 지정하려면 해당하는 Content-Type을 포함하고 필요한 경우 Accept 헤더도 포함합니다.
- 엔터티를 만들 때 응답 콘텐츠 에코를 표시하지 않으려면 변경 집합의 각 삽입 작업에 대해 return-no-content 값을 포함하는 Prefer 헤더를 지정합니다.
샘플 요청
다음 예제에서는 아래의 5개 항목이 포함된 일괄 처리 요청을 보여 줍니다.
- testuser@contoso.onmicrosoft.com 사용자를 만드는 변경 집합(POST). 이 작업에는 새로 작성되어 반환되는 사용자를 표시하지 않도록 response-no-content 헤더가 포함됩니다.
- 새 사용자의 Department 및 Job Title 속성을 업데이트하고(PATCH) 해당 관리자 탐색 속성을 설정(PUT)하는 변경 집합
- 새 사용자의 관리자에 대한 쿼리(GET)
- 새 사용자를 삭제하는 변경 집합(DELETE)
- 사용자에 대한 쿼리(GET). 이전 단계에서 사용자가 삭제되었으므로 이 작업은 실패합니다.
POST https://graph.windows.net/contoso.onmicrosoft.com/$batch?api-version=1.5 HTTP/1.1
Authorization: Bearer ey … jQA
Content-Type: multipart/mixed; boundary=batch_36522ad7-fc75-4b56-8c71-56071383e77b
Host: graph.windows.net
Content-Length: 2961
--batch_36522ad7-fc75-4b56-8c71-56071383e77b
Content-Type: multipart/mixed; boundary=changeset_77162fcd-b8da-41ac-a9f8-9357efbbd620
Content-Length: 631
--changeset_77162fcd-b8da-41ac-a9f8-9357efbbd620
Content-Type: application/http
Content-Transfer-Encoding: binary
POST /contoso.onmicrosoft.com/users?api-version=1.5 HTTP/1.1
Content-Type: application/json
Accept: application/json
Content-Length: 256
Prefer: return-no-content
Host: graph.windows.net
{
"accountEnabled": true,
"displayName": "Test User",
"mailNickname": "testuser",
"passwordProfile": { "password" : "Test1234", "forceChangePasswordNextLogin": false },
"userPrincipalName": "testuser@contoso.onmicrosoft.com"
}
--changeset_77162fcd-b8da-41ac-a9f8-9357efbbd620----batch_36522ad7-fc75-4b56-8c71-56071383e77b
Content-Type: multipart/mixed; boundary=changeset_4b2cbfb7-011d-4edb-8bbf-e044f9830aaf
Content-Length: 909
--changeset_4b2cbfb7-011d-4edb-8bbf-e044f9830aaf
Content-Type: application/http
Content-Transfer-Encoding: binary
PATCH /contoso.onmicrosoft.com/users/testuser@contoso.onmicrosoft.com?api-version=1.5 HTTP/1.1
Content-Type: application/json
Accept: application/json
Content-Length: 72
Host: graph.windows.net
{
"department": "Engineering",
"jobTitle": "Test Engineer"
}
--changeset_4b2cbfb7-011d-4edb-8bbf-e044f9830aaf
Content-Type: application/http
Content-Transfer-Encoding: binary
PUT /contoso.onmicrosoft.com/users/testuser@contoso.onmicrosoft.com/$links/manager?api-version=1.5 HTTP/1.1
Content-Type: application/json
Accept: application/json
Content-Length: 112
Host: graph.windows.net
{
"url":"https://graph.windows.net/contoso.onmicrosoft.com/users/a71e4d1c-ce99-40dc-8d4b-390eac63e039"
}
--changeset_4b2cbfb7-011d-4edb-8bbf-e044f9830aaf----batch_36522ad7-fc75-4b56-8c71-56071383e77b
Content-Type: application/http
Content-Transfer-Encoding:binary
GET /contoso.onmicrosoft.com/users/testuser@contoso.onmicrosoft.com/$links/manager?api-version=1.5 HTTP/1.1
Accept: application/json
Host: graph.windows.net
--batch_36522ad7-fc75-4b56-8c71-56071383e77b
Content-Type: multipart/mixed; boundary=changeset_9a0b5878-0f4a-4f57-91c5-9792cdd5ef20
Content-Length: 331
--changeset_9a0b5878-0f4a-4f57-91c5-9792cdd5ef20
Content-Type: application/http
Content-Transfer-Encoding: binary
DELETE /contoso.onmicrosoft.com/users/testuser@contoso.onmicrosoft.com?api-version=1.5 HTTP/1.1
Accept: application/json
Host: graph.windows.net
--changeset_9a0b5878-0f4a-4f57-91c5-9792cdd5ef20----batch_36522ad7-fc75-4b56-8c71-56071383e77b
Content-Type: application/http
Content-Transfer-Encoding:binary
GET /contoso.onmicrosoft.com/users/testuser@contoso.onmicrosoft.com?api-version=1.5 HTTP/1.1
Accept: application/json
Host: graph.windows.net
--batch_36522ad7-fc75-4b56-8c71-56071383e77b--
일괄 처리 응답 구문
응답은 일괄 처리 요청에 대한 전반적인 상태 코드와 일괄 처리의 각 항목에 대한 개별 상태 코드 및 결과 조각을 반환합니다. 응답은 일괄 처리 경계 및 변경 집합 경계를 포함하는 다중 파트 MIME 메시지입니다.
일괄 처리 요청이 올바르게 인증되었고 Graph API에서 정상적으로 수신되었다고 가정하면 일괄 처리 요청은 일괄 처리의 작업 중 하나가 실패하더라도 상태 코드 202 승인됨을 반환합니다. 일괄 처리 요청 자체가 실패하면 일괄 처리의 다른 작업이 실행되기 전에 먼저 실패합니다. 예를 들어 인증 오류로 인해 일괄 처리 요청이 실패할 수 있으며, 이 경우 상태 코드로 해당 오류가 표시됩니다.
쿼리 항목의 응답 조각에는 작업 성공 또는 실패를 나타내는 상태 코드 하나와 그에 해당하는 응답 본문이 포함됩니다.
변경 집합의 작업은 원자성으로 처리됩니다. 즉, 변경 집합의 모든 작업이 성공하거나 전체 변경 집합이 실패합니다. Graph API는 실패하는 작업이 있을 때까지 변경 집합의 작업 처리를 계속합니다. 작업이 실패하면 변경 집합의 모든 이전 작업이 롤백됩니다.
변경 집합의 모든 작업이 정상적으로 처리되면 변경 집합 내 각 작업의 상태 코드와 응답 본문이 변경 집합 응답 내에 표시됩니다. 변경 집합의 작업이 실패하면 변경 집합에 대해 단일 상태 코드만 반환됩니다. 이 경우 400 잘못된 요청 또는 404 찾을 수 없음과 같이 실패한 작업에서 반환하는 상태 코드와 응답 본문이 반환됩니다.
샘플 응답
다음 예제에는 위에 나와 있는 샘플 요청에서 전송된 일괄 처리 작업의 응답이 나와 있습니다. 일괄 처리 요청 자체의 상태는 202 승인됨으로 설정됩니다. 이 상태는 일괄 처리 요청 자체에는 문제가 없음을 나타냅니다. 일괄 처리의 각 항목에 대한 응답은 batchresponse 경계 식별자로 구분되며 변경 집합 내의 작업에 대한 각 응답은 changesetresponse 경계 식별자로 구분됩니다.
아래에는 각 일괄 처리 항목에 대한 응답 조각의 목록이 나와 있습니다.
- 새 사용자를 만들기 위한 POST 요청의 상태는 204 콘텐츠 없음으로 설정됩니다. 요청에서 Prefer 헤더가
return-no-content
로 설정되었기 때문입니다. 이 상태는 사용자가 정상적으로 작성되었음을 나타냅니다. - 두 번째 일괄 처리 항목의 응답에는 204 콘텐츠 없음* 응답 두 개가 포함됩니다. 그중 하나는 사용자 개체 업데이트(PATCH)에 대한 응답이고 나머지 하나는 변경 집합에서 관리자 링크를 설정(PUT)하는 작업에 대한 응답입니다. 이 응답은 두 작업이 모두 정상적으로 수행되었음을 나타냅니다.
- 사용자의 관리자를 읽는 요청에 대한 응답에서는 관리자의 링크와 200 확인 상태가 반환됩니다.
- 사용자 삭제 작업의 상태는 204 콘텐츠 없음입니다. 이 상태는 작업이 정상적으로 수행되었음을 나타냅니다.
- 삭제된 사용자 읽기 작업의 상태는 404 찾을 수 없음이고 응답에는 사용자(리소스)를 찾을 수 없음을 나타내는 메시지와 코드가 포함됩니다.
HTTP/1.1 202 Accepted
Cache-Control: no-cache
Pragma: no-cache
Content-Type: multipart/mixed; boundary=batchresponse_1eb70252-25d2-466c-9a1d-7a3f45378b06
Expires: -1
Server: Microsoft-IIS/8.5
ocp-aad-diagnostics-server-name: Nv0YIi2YUldDWu0YPQAXsYwXQ4ttyr7ded6Waf8xyCc=
request-id: 2f7d2f81-3441-4c2a-b494-25cd1d6ce624
client-request-id: f40c00af-3e1f-4198-9261-386f0e3aecc6
x-ms-gateway-rewrite: false
x-ms-dirapi-data-contract-version: 1.5
ocp-aad-session-key: cdhenl3mgHuI3vaRRIQ14uXdwRLUqirNpDXjJP42EzUEvqhhn2NFr22ulR4PsqrM1UD_eSUDItt7J9kUQhNvTT_48q90coHHt2RutCIgPNg.lD81Z0iS2SaHbqkfAaDvbbigoX7ak7rfiUGFby0LOIE
X-Content-Type-Options: nosniff
DataServiceVersion: 1.0;
Strict-Transport-Security: max-age=31536000; includeSubDomains
X-AspNet-Version: 4.0.30319
X-Powered-By: ASP.NET
X-Powered-By: ASP.NET
Date: Tue, 20 Jan 2015 23:21:15 GMT
Content-Length: 3065
--batchresponse_1eb70252-25d2-466c-9a1d-7a3f45378b06
Content-Type: multipart/mixed; boundary=changesetresponse_8a63ce5e-ed31-4de6-bc90-9d3ff31debbb--changesetresponse_8a63ce5e-ed31-4de6-bc90-9d3ff31debbb
Content-Type: application/http
Content-Transfer-Encoding: binary
HTTP/1.1 204 No Content
X-Content-Type-Options: nosniff
Cache-Control: no-cache
Preference-Applied: return-no-content
DataServiceVersion: 3.0;
Location: https://graph.windows.net/contoso.onmicrosoft.com/directoryObjects/6a287a96-ede9-44d2-b685-d6fc03a124c5/Microsoft.DirectoryServices.User
DataServiceId: https://graph.windows.net/contoso.onmicrosoft.com/directoryObjects/6a287a96-ede9-44d2-b685-d6fc03a124c5
--changesetresponse_8a63ce5e-ed31-4de6-bc90-9d3ff31debbb----batchresponse_1eb70252-25d2-466c-9a1d-7a3f45378b06
Content-Type: multipart/mixed; boundary=changesetresponse_11ba5cf0-9fba-4995-9f15-bd5c9981cdd6--changesetresponse_11ba5cf0-9fba-4995-9f15-bd5c9981cdd6
Content-Type: application/http
Content-Transfer-Encoding: binary
HTTP/1.1 204 No Content
X-Content-Type-Options: nosniff
Cache-Control: no-cache
DataServiceVersion: 1.0;
--changesetresponse_11ba5cf0-9fba-4995-9f15-bd5c9981cdd6
Content-Type: application/http
Content-Transfer-Encoding: binary
HTTP/1.1 204 No Content
X-Content-Type-Options: nosniff
Cache-Control: no-cache
DataServiceVersion: 1.0;
--changesetresponse_11ba5cf0-9fba-4995-9f15-bd5c9981cdd6----batchresponse_1eb70252-25d2-466c-9a1d-7a3f45378b06
Content-Type: application/http
Content-Transfer-Encoding: binary
HTTP/1.1 200 OK
DataServiceVersion: 3.0;
Content-Type: application/json;odata=minimalmetadata;streaming=true;charset=utf-8
X-Content-Type-Options: nosniff
Cache-Control: no-cache
{
"odata.metadata":"https://graph.windows.net/contoso.onmicrosoft.com/$metadata#directoryObjects/$links/manager",
"url":"https://graph.windows.net/contoso.onmicrosoft.com/directoryObjects/a71e4d1c-ce99-40dc-8d4b-390eac63e039/Microsoft.DirectoryServices.User"
}
--batchresponse_1eb70252-25d2-466c-9a1d-7a3f45378b06
Content-Type: multipart/mixed; boundary=changesetresponse_bb215a84-f91e-4486-a771-ba2cc5d429d1--changesetresponse_bb215a84-f91e-4486-a771-ba2cc5d429d1
Content-Type: application/http
Content-Transfer-Encoding: binary
HTTP/1.1 204 No Content
X-Content-Type-Options: nosniff
Cache-Control: no-cache
DataServiceVersion: 1.0;
--changesetresponse_bb215a84-f91e-4486-a771-ba2cc5d429d1----batchresponse_1eb70252-25d2-466c-9a1d-7a3f45378b06
Content-Type: application/http
Content-Transfer-Encoding: binary
HTTP/1.1 404 Not Found
X-Content-Type-Options: nosniff
Cache-Control: no-cache
DataServiceVersion: 3.0;
Content-Type: application/json;odata=minimalmetadata;streaming=true;charset=utf-8
{
"odata.error":
{
"code":"Request_ResourceNotFound",
"message":
{
"lang":"en",
"value":"Resource 'testuser@contoso.onmicrosoft.com' does not exist or one of its queried reference-property objects are not present."
}
}
}
--batchresponse_1eb70252-25d2-466c-9a1d-7a3f45378b06--
샘플 오류 응답
위에서 설명한 것처럼 Graph API는 일괄 처리 요청의 형식이 올바르며 인증 오류 등의 오류가 없어 일괄 처리를 허용할 수 있으면 전체 일괄 처리에 대해 오류 코드 202 승인됨을 반환합니다. 그렇지 않으면 해당하는 오류가 반환되며 일괄 처리가 처리되지 않습니다. 일괄 처리 내의 개별 항목이 실패하면 해당 항목에 대한 응답 조각에는 오류를 나타내는 응답 본문과 상태 코드가 포함됩니다. 변경 집합 내의 작업이 실패하면 전체 변경 집합에 대해 단일 응답 조각이 반환되며, 해당 조각에는 실패한 작업과 관련된 응답 본문 및 상태 코드가 포함됩니다.
다음 예제에서는 작업 중 하나가 실패한 변경 집합이 포함된 일괄 처리 요청의 응답을 보여 줍니다. 일괄 처리 응답은 상태 코드 202 승인됨을 반환합니다. 변경 집합에 대해 반환되는 상태 코드는 작업이 실패했으며 상태가 404 찾을 수 없음임을 나타냅니다. 추가 오류 정보는 실패한 작업의 응답 본문에 포함됩니다. code 요소는 Graph API 오류 코드를 지정하며 message 요소는 오류 메시지 문자열을 포함합니다. 이 예제에서는 보다 쉽게 읽을 수 있도록 응답 본문을 들여썼습니다.
HTTP/1.1 202 Accepted
Cache-Control: no-cache
Pragma: no-cache
Content-Type: multipart/mixed; boundary=batchresponse_3ac28387-a100-4758-8998-8b9ec36f9fdc
Expires: -1
Server: Microsoft-IIS/8.5
ocp-aad-diagnostics-server-name: 1l3fvSoDCV+VKoBCuHRN+HIwCACBOck3dqmtCGj+aiU=
request-id: e434261b-c32f-48b4-b21d-3e1beab6d525
client-request-id: 236bf26e-b4e8-40a4-b6fb-d41105a7b178
x-ms-gateway-rewrite: false
x-ms-dirapi-data-contract-version: 1.5
ocp-aad-session-key: 9aOaAUxX95OZ0ctrYbeLUproN-37GypZXrss0PYKhEfqamKRG-C68hFcCw5h-ZCWFqBrXPrldGEnjq4CKKr0bW91tjrdo-BlwAqHxbP5jq4.FaXtVZni3cSsWFRMSjQAbjiluPcEvZofwp9OH3t1fyk
X-Content-Type-Options: nosniff
DataServiceVersion: 1.0;
Strict-Transport-Security: max-age=31536000; includeSubDomains
X-AspNet-Version: 4.0.30319
X-Powered-By: ASP.NET
X-Powered-By: ASP.NET
Date: Wed, 21 Jan 2015 21:13:25 GMT
Content-Length: 779
--batchresponse_3ac28387-a100-4758-8998-8b9ec36f9fdc
Content-Type: multipart/mixed; boundary=changesetresponse_72ba9a5a-2da3-4d39-ae4f-dd9527efd742--changesetresponse_72ba9a5a-2da3-4d39-ae4f-dd9527efd742
Content-Type: application/http
Content-Transfer-Encoding: binary
HTTP/1.1 404 Not Found
X-Content-Type-Options: nosniff
DataServiceVersion: 3.0;
Content-Type: application/json;odata=minimalmetadata;streaming=true;charset=utf-8
{
"odata.error":
{
"code":"Request_ResourceNotFound",
"message":
{
"lang":"en",
"value":"Resource 'eeeeeeee-eeee-eeee-eeee-eeeeeeeeeeee' does not exist or one of its queried reference-property objects are not present."
}
}
}
--changesetresponse_72ba9a5a-2da3-4d39-ae4f-dd9527efd742----batchresponse_3ac28387-a100-4758-8998-8b9ec36f9fdc--
참조용으로 제공되는 다음 예제는 위 응답을 생성한 일괄 처리를 보여 줍니다. 여기에는 그룹에 사용자 3명을 추가하는 변경 집합 하나가 포함되어 있습니다. 마지막 두 사용자의 개체 ID는 가상의 값인 eeeeeeee-eeee-eeee-eeee-eeeeeeeeeeee 및 ffffffff-ffff-ffff-ffff-ffffffffffff입니다. 코드를 간략하게 작성하기 위해 일괄 처리 URL과 연결된 요청 헤더는 생략했습니다.
--batch_36522ad7-fc75-4b56-8c71-56071383e77b
Content-Type: multipart/mixed; boundary=changeset_5a769eb2-d1a7-4a10-94f6-d1a5ed5c4bc0
Content-Length: 1432
--changeset_5a769eb2-d1a7-4a10-94f6-d1a5ed5c4bc0
Content-Type: application/http
Content-Transfer-Encoding: binary
POST /contoso.onmicrosoft.com/groups/fc15e7ef-993f-4865-bf37-317d9b8017b8/$links/members?api-version=1.5 HTTP/1.1
Content-Type: application/json
Accept: application/json
Content-Length: 112
Host: graph.windows.net
{
"url":"https://graph.windows.net/contoso.onmicrosoft.com/users/a71e4d1c-ce99-40dc-8d4b-390eac63e039"
}
--changeset_5a769eb2-d1a7-4a10-94f6-d1a5ed5c4bc0
Content-Type: application/http
Content-Transfer-Encoding: binary
POST /contoso.onmicrosoft.com/groups/fc15e7ef-993f-4865-bf37-317d9b8017b8/$links/members?api-version=1.5 HTTP/1.1
Content-Type: application/json
Accept: application/json
Content-Length: 112
Host: graph.windows.net
{
"url":"https://graph.windows.net/contoso.onmicrosoft.com/users/eeeeeeee-eeee-eeee-eeee-eeeeeeeeeeee
"
}
--changeset_5a769eb2-d1a7-4a10-94f6-d1a5ed5c4bc0
Content-Type: application/http
Content-Transfer-Encoding: binary
POST /contoso.onmicrosoft.com/groups/fc15e7ef-993f-4865-bf37-317d9b8017b8/$links/members?api-version=1.5 HTTP/1.1
Content-Type: application/json
Accept: application/json
Content-Length: 112
Host: graph.windows.net
{
"url":"https://graph.windows.net/contoso.onmicrosoft.com/users/ffffffff-ffff-ffff-ffff-ffffffffffff"
}
--changeset_5a769eb2-d1a7-4a10-94f6-d1a5ed5c4bc0----batch_36522ad7-fc75-4b56-8c71-56071383e77b--