References
- Microsoft Learn(Use the Microsoft Graph API)
- Microsoft Learn(엑세스 토큰 발급 방안 - Client Credentials Type 사용)
- Microsoft Learn(OData Documentation)
- OData(Blog 1)
- OData(Blog 2)
- OData(Wiki)
- Microsoft Learn(OData Query Parameter)
- GraphQL(Kakao Tech Blog) (나중에 읽어보기!)
💡 OData (Open Data Protocol) 란
- 간단하고 표준적인 방식으로 쿼리 가능하고 상호 운용 가능한 REST API 를 만들고 사용할 수 있는 개방형 프로토콜 (CRUDQ (Create, Read, Update, Delete, Query) 작업 지원)
- 서비스 제공자 입장에서 웹으로 데이터를 제공하는 방식으로 오픈된 공통규약
- 웹 클라이언트가 간단한 HTTP 메시지를 사용 하여 쿼리문을 호출, 해당 URL을 식별하여 데이터 모델 에 정의된 리소스를 생성 및 수정 가능
- Microsoft 는 OData 를 2007년에 사용 시작
💡 OData EntityData Model (EDM) 이란 (추가 스터디 필요..)


- Entity Data Model (EDM) 이란 OData 서비스에서 노출하는 데이터(리소스)를 설명하는데 사용되는 추상 데이터 모델
- OData 메타데이터 문서에는 클라이언트의 사용을 위해 노출된 서비스의 데이터 모델을나타낸다.
😕 추가 스터디 필요 (용어 정리 참고 1) (용어 정리 참고2)
→ 엔티티는 일종의 데이터 셋 (고객, 직원) 이고 엔티티 셋은 그러한 엔티티의 집합,
→ 각 엔티티는 Navigation Property를 (탐색 속성) 갖고 (일종의 URL Path Parameter 와 같은) 으로 상세 구분되어 쿼리 가능
Entity | Entity는 Entity Type 의 인스턴스 (ex. 고객, 직원) |
|---|---|
Entity Type | 키가 있는 구조화된 유형, Entity의 Property(속성) 과 Relationship(관계) 를 정의 |
Complex types | 키 없이 Property(속성) 집합으로 구조화된 유형(?), 외부에서 인스턴스를 참조할 수 없는 값 유형 |
Properties | 구조화된 유형 정의의 일부로 선언된 속성과 추가로 선언되지 않은 동적 속성이 포함, 선언된 속성과 동적 속성은 동일한 이름을 가질 수 없다. |
Relationships | navigation property (탐색 속성)으로 표시, 일반적으로 Entity Type의 일부로 정의되지만, 선언되지 않은 동적 Navigation property 로도 나타낼 수 있음..(?) |
Enumeration | Enumeration(열거) 형은 값이 기본 정수, 상수 값을 갖는 명명된 기본유형 |
Entity sets | 명명된 Entity 모음, Entity Key는 Entity Set 내 Entity를 고유하게 식별, 각 Entity 에는 고유하고 서로 다른 Entity Id가 존재 |
Operations | 작업을 통해 데이터 모델의 일부에서 사용자 지정 논리를 실행 |
Singletons | Entity Container의 직계 자식으로 액세스할 수 있는 명명된 Entity, 싱글톤은 Entity Set 의 구성일 수 도 있다. |
💡 Microsoft Graph API 란
- Microsoft 클라우드 서비스 리소스에 접근할 수 있는 RESTful API
- Azure 에 앱을 등록 하고, 등록 된 앱에서 Client ID, Secret 확인 가능 (인증 Flow에 사용)
- App 관리자는 해당 앱에 대한 인증서, 범위, 사용자 할당 등의 상세 설정

등록 된 앱 예시 - Application Id, Tenant Id 확인 및 Manage 탭에서 각종 설정 가능
※ SK 바이오사이언스 OData API 호출 방안
❌ ~~[방안 1]webMethods API Gateway 에서 OData API 직접 등록 (ex. Microsoft Graph API)~~ (뻘짓)
- Import API from URL 방식으로 Create API (https://graph.microsoft.com/v1.0)
- Swagger UI 에서 호출 가능한지 테스트 필요 (API Portal Try-Out 가능한지)
- Policy 에서 Custom Extension 으로 Access Token 발급 & Set Header (Authorization)

Import API from URL (https://graph.microsoft.com/v1.0/) 로 등록 (API 확인을 위해 임시 API 등록)

등록 된 OData API 리스트

등록 된 OData singletons 예시

Navigation properties
⭕ [방안 2]Request Parameter 처리 방안
- 참고 OData Parameter (V4 query language)
[2-1]하나의 파라미터로 받아 처리 (Description에 설명 추가)[2-2]또는 Request Parameter 에 OData Parameter 설정이 가능한지 테스트 필요- [2-3] In/Output (Required : true/false) 만 설정 하고 호출받은 Query 그대로 전달
- transportInfo 의 query는 인코딩 됨 (’&’) 방화벽 오픈 후 테스트 필요
- OData API 는 REST API 의 일부 = Swagger UI 에서 호출 가능
- REST API 로 생성 시 (CUDO Portal Try-out 문제 없음)
💡 API 개발 상세
- 호출 Try-Out → Graph Explorer 참고
- 22/12/08 기준 SKBS 개발서버 I/F 캡처
✅ [COMMON I/F] Access Token 발급 호출 (Client Credentials Type)
- [POST]https://login.microsoftonline.com/{tenant ID}/oauth2/v2.0/token
📌 토큰 관리 방안 추가 확인 필요
→ 토큰 만료시 관리 방안 배치 작업으로 토큰 재발급 & 캐싱 (22/12/08)❓
## **호출 예시 ##**[**POST]** <https://login.microsoftonline.com/{tenant}/oauth2/v2.0/token> HTTP/1.1## **Request Header ##****Host:** login.microsoftonline.com**Content-Type:** application/x-www-form-urlencoded## **Request Body ##****client_id**=535fb089-9ff3-47b6-9bfb-4f1264799865&**scope**=https%3A%2F%2Fgraph.microsoft.com%2F.default&**client_secre**t=qWgdYAmab0YSkuL1qKv5bPX&**grant_type**=client_credentials
Parameter | Condition | Description |
|---|---|---|
tenant | required | 권한을 요청하려는 디렉터리 테넌트의 ID 값 |
client_id | required | Azure AD 앱 등록 시 할당 된 애플리케이션 ID입니다 . |
scope | required | .default접미사 가 붙은 원하는 리소스의 식별자(앱 ID URI) |
→ Microsoft Graph의 경우 범위https://graph.microsoft.com/.default 값은 관리자가 동의한 모든 앱 수준 권한을 액세스 토큰에 포함하는 Scope 값 | ||
client_secret | required | 앱 등록 포털에서 앱에 대해 생성한 클라이언트 암호, URL이 인코딩되어 있는지 확인. |
grant_type | required | client_credentials. |

svc_GET_ACCESS_TOKEN

util_GET_TOKEN_FROM_CACHE
✅ [MSC_IF0001] My profile
- Request Parameter
- $select (Optional) → Input/Output 에 Requred : False 설정
- Request Header
- Authorization : Bearer {access_token}
- Response
- 200 OK + Response body
- 202 Accepted → 성공적으로 처리되었지만 서버가 관련된 백그라운드 작업을 완료하는 데 더 많은 시간이 필요할 때 반환
<<업로드 제한으로 << Notion에 작성>>
svc_MSC_IF0001
✅ [MSC_IF0002] My photo
- Request Parameter (OData V.4 Query Parameter)→ $value url 파라미터 제외 나머지 OData Paramter Required : False 설정[파라미터 상세]
- System query options
Name | Description |
|---|---|
$count | 일치하는 리소스의 총 수를 검색 |
$expand | 관련 리소스를 검색 |
$filter | 결과(행)를 필터링 |
$format | 지정된 미디어 형식으로 결과를 반환 |
$orderby | 결과를 주문 |
$search | 검색 기준에 따라 결과를 반환 |
$select | 속성(열)을 필터링 |
$skip | 결과 집합으로 인덱스, $top또한 일부 API에서 페이징을 구현하는 데 사용되며 결과를 수동으로 페이징하는 데 함께 사용할 수 있다 |
$top | 결과의 페이지 크기를 설정 |
- Other query parameters
Name | Description |
|---|---|
$skipToken | 여러 페이지에 걸쳐 있는 결과 집합에서 결과의 다음 페이지를 검색 (일부 API는 $skip대신 사용) |
- Other Odata URL capabilities
Name | Description |
|---|---|
$count | 컬렉션의 정수 합계를 검색 |
$ref | 컬렉션에 대한 엔터티 멤버십을 업데이트 |
$value | 항목의 이진 값을 검색하거나 업데이트 |
$batch | 여러 HTTP 요청을 일괄 요청으로 결합 |
- Request Header
- Authorization : Bearer {access_token}
- Response
- 200 OK
- 404 Not found
<<업로드 제한으로 << Notion에 작성>>
svc_MSC_IF0002
✅ [MSC_IF0003] My mail
- Request Parameter
- MSC_IF0002 와 동일
- Request Header
- Authorization : Bearer {access_token}
- (Prefer) outlook.body-content-type
- 반환할 본문 및 uniqueBody 속성의 형식, 값은 "text" 또는 "html", 헤더를 지정하지 않으면 body 및 uniqueBody 속성이 HTML (Default), (Optional 헤더)
- Response
- 200 OK → Message 객체 컬렉션 반환
<<업로드 제한으로 << Notion에 작성>>
svc_MSC_IF0003
✅ [MSC_IF0004] My manager
- Request Parameter
- MSC_IF0002 와 동일
Note. (Description → API Gateway Description 추가)
- The n value of $levels can be max (to return all managers) or a number between 1 and 1000.
- When the $levels parameter is not specified, only the immediate manager is returned.
- You can specify $select inside $expand to select the individual manager's properties. The $levels parameter is required: $expand=manager($levels=max;$select=id,displayName).
- $levels parameter is only supported on a single user (/users/{id} or me endpoints) and not on the entire list of users.
- $levels requires the ConsistencyLevel header set to eventual and $count=true in query string. For more information about the use of ConsistencyLevel and $count, see Advanced query capabilities on Azure AD directory objects.
- Request Header
- Authorization : Bearer {access_token}
- 🔔**(eventual)** ConsistencyLevel : $count=true 쿼리 문자열이 포함된 경우 필요
- Response
- 200 OK → directoryObject 개체 반환
<<업로드 제한으로 << Notion에 작성>>
svc_MSC_IF0004
✅ [MSC_IF0005] All the items in my drive
- Request Parameter
- MSC_IF0002 와 동일
- Request Header
- ❓ Authorization : Bearer {access_token}
- (Optional) if-none-match [etag] (테스트 필요)
- Response
- 200 OK
<<업로드 제한으로 << Notion에 작성>>