오픈 데이터 프로토콜

컴퓨팅에서 **오픈 데이터 프로토콜**(Open Data Protocol, **OData**)은 표준적인 방식으로 쿼리 가능하고 상호 운용 가능한 웹 서비스 API를 생성하고 소비할 수 있게 하는 공개 프로토콜이다. 마이크로소프트는 2007년에 OData를 시작했다. 버전 1.0, 2.0, 3.0은 마이크로소프트 오픈 스펙 약속 하에 릴리스되었다. 버전 4.0은 OASIS에서 표준화되었으며, 2014년 3월에 출시되었다. 2015년 4월 OASIS는 OData v4와 OData JSON Format v4를 ISO/IEC JTC 1에 국제 표준으로 승인해달라고 제출했다. 2016년 12월, ISO/IEC는 OData 4.0 Core를 ISO/IEC 20802-1:2016으로, OData JSON Format을 ISO/IEC 20802-2:2016으로 출판했다.

이 프로토콜은 HTTP 기반의 웹 API 생성 및 소비를 가능하게 하며, 웹 클라이언트가 URL을 사용하여 식별되고 데이터 모델에서 정의된 리소스를 간단한 HTTP 메시지를 사용하여 게시하고 편집할 수 있게 한다. OData는 JDBC 및 ODBC와 유사한 점을 공유하며, ODBC와 마찬가지로 OData는 관계형 데이터베이스에만 국한되지 않는다.

## 표준화
마이크로소프트의 초기 개발 이후, OData는 OASIS OData 기술 위원회(TC)의 표준화된 프로토콜이 되었다.

### OASIS OData 기술 위원회
"OASIS OData TC는 기업, 클라우드, 모바일 기기에서 재사용을 위해 서로 다른 애플리케이션 및 여러 이해관계자 간에 데이터를 쿼리하고 공유하는 것을 단순화하기 위해 노력한다. REST 기반 프로토콜인 OData는 HTTP, AtomPub, JSON을 기반으로 구축되었으며 URI를 사용하여 데이터 피드 리소스에 접근한다. 이 프로토콜은 관계형 데이터베이스, 파일 시스템, 콘텐츠 관리 시스템, 전통적인 웹 사이트를 포함한(이에 국한되지 않음) 다양한 소스에서 정보에 접근할 수 있게 한다. OData는 데이터 사일로를 허물고 데이터의 공유 가치를 높이는 방법을 제공하며, 데이터 소비자가 데이터 생산자와 현재 가능한 것보다 훨씬 강력한 방식으로 상호 운용할 수 있는 생태계를 조성하여 더 많은 애플리케이션이 더 넓은 범위의 데이터를 이해할 수 있도록 한다. 이 생태계에 참여하는 모든 데이터 생산자와 소비자는 그 전체 가치를 증가시킨다."


TC 참가자로는 CA 테크놀로지스, 시트릭스 시스템즈, IBM, 마이크로소프트, 프로그레스 소프트웨어, 레드햇, SAP SE 및 SDL이 있다.

## 아키텍처
OData는 웹 API 생성 및 소비를 위한 프로토콜이다. 따라서 OData는 URI를 사용하여 데이터 피드 리소스에 접근하는 HTTP, AtomPub 및 JSON을 기반으로 한다.

### 리소스 식별
OData는 URI를 사용하여 리소스를 식별한다. 서비스 루트가 http://host/service/로 약칭되는 모든 OData 서비스에 대해 다음의 **고정** 리소스를 찾을 수 있다.

#### 서비스 문서
서비스 문서는 검색할 수 있는 엔티티 집합, 함수 및 싱글턴을 나열한다. 클라이언트는 서비스 문서를 사용하여 하이퍼미디어 기반 방식으로 모델을 탐색할 수 있다.

서비스 문서는 http://host/service/에서 이용할 수 있다.

#### 메타데이터 문서
메타데이터 문서는 OData 서비스가 이해하는 형식, 집합, 함수 및 작업을 설명한다. 클라이언트는 메타데이터 문서를 사용하여 서비스의 엔티티를 쿼리하고 상호 작용하는 방법을 이해할 수 있다.

메타데이터 문서는 http://host/service/$metadata에서 이용할 수 있다.

#### 동적 리소스
동적 리소스의 URI는 서비스 문서 및 메타데이터 문서의 하이퍼미디어 정보로부터 계산될 수 있다.

### 리소스 작업
OData는 HTTP 동사를 사용하여 리소스에 대한 작업을 나타낸다.
* GET: 리소스(엔티티 컬렉션, 단일 엔티티, 구조적 속성, 탐색 속성, 스트림 등)를 가져온다.
* POST: 새 리소스를 생성한다.
* PUT: 기존 리소스를 완전한 인스턴스로 교체하여 업데이트한다.
* PATCH: 기존 리소스의 일부 속성을 부분 인스턴스로 교체하여 업데이트한다.
* DELETE: 리소스를 제거한다.

### 쿼리
OData 엔드포인트에 요청된 URL에는 쿼리 옵션이 포함될 수 있다. OData 프로토콜은 엔드포인트가 수락해야 하는 다양한 '시스템 쿼리 옵션'을 지정하며, 이는 데이터를 필터링, 정렬, 매핑 또는 페이지 매김하는 데 사용할 수 있다.

쿼리 옵션은 `?` 문자 뒤에 URL에 추가할 수 있으며 `&` 문자로 구분된다. 각 옵션은 `$` 부호가 접두사로 붙은 이름과 그 값으로 구성되며 `=` 부호로 구분된다. 예를 들어 `OData/Products?$top=2&$orderby=Name`과 같다. 데이터를 필터링할 때 사용할 수 있도록 여러 논리 연산자와 함수가 정의되어 있다. 예를 들어 `OData/Products?$filter=Price lt 10.00 and startswith(Name,'M')`은 가격이 10보다 작고 이름이 'M'으로 시작하는 제품을 요청한다.

### 리소스 표현
OData는 데이터 및 데이터 모델을 표현하기 위해 다양한 형식을 사용한다. OData 프로토콜 버전 4.0에서는 JSON 형식이 데이터 표현의 표준이며, Atom 형식은 여전히 위원회 사양 단계에 있다. 데이터 모델을 표현하기 위해서는 OData 서비스가 노출하는 엔티티 데이터 모델의 XML 표현을 정의하는 CSDL(Common Schema Definition Language)이 사용된다.

#### OData JSON 데이터 페이로드 샘플
제품 컬렉션:

```json
{
  "@odata.context": "http://services.odata.org/V4/OData/OData.svc/$metadata#Products",
  "value": [
    {
      "ID": 0,
      "Name": "Meat",
      "Description": "Red Meat",
      "ReleaseDate": "1992-01-01T00:00:00Z",
      "DiscontinuedDate": null,
      "Rating": 14,
      "Price": 2.5
    },
    {
      "ID": 1,
      "Name": "Milk",
      "Description": "Low fat milk",
      "ReleaseDate": "1995-10-01T00:00:00Z",
      "DiscontinuedDate": null,
      "Rating": 3,
      "Price": 3.5
    },
    ...
  ]
}
```


#### OData Atom 데이터 페이로드 샘플
제품 컬렉션:

```xml
<feed xml:base="http://services.odata.org/V4/OData/OData.svc/" m:context="http://services.odata.org/V4/OData/OData.svc/$metadata#Products" xmlns="http://www.w3.org/2005/Atom" xmlns:d="http://docs.oasis-open.org/odata/ns/data" xmlns:m="http://docs.oasis-open.org/odata/ns/metadata" xmlns:georss="http://www.georss.org/georss" xmlns:gml="http://www.opengis.net/gml">
  <id>http://services.odata.org/v4/odata/odata.svc/Products</id>
  <title type="text">Products</title>
  <updated>2015-05-19T03:38:50Z</updated>
  <link rel="self" title="Products" href="Products"/>
  <entry>
    <id>http://services.odata.org/V4/OData/OData.svc/Products(0)</id>
    <category term="#ODataDemo.Product" scheme="http://docs.oasis-open.org/odata/ns/scheme"/>
    <link rel="edit" title="Product" href="Products(0)"/>
    <link rel="http://docs.oasis-open.org/odata/ns/relatedlinks/Categories" type="application/xml" title="Categories" href="Products(0)/Categories/$ref"/>
    <link rel="http://docs.oasis-open.org/odata/ns/related/Categories" type="application/atom+xml;type=feed" title="Categories" href="Products(0)/Categories"/>
    <link rel="http://docs.oasis-open.org/odata/ns/relatedlinks/Supplier" type="application/xml" title="Supplier" href="Products(0)/Supplier/$ref"/>
    <link rel="http://docs.oasis-open.org/odata/ns/related/Supplier" type="application/atom+xml;type=entry" title="Supplier" href="Products(0)/Supplier"/>
    <link rel="http://docs.oasis-open.org/odata/ns/relatedlinks/ProductDetail" type="application/xml" title="ProductDetail" href="Products(0)/ProductDetail/$ref"/>
    <link rel="http://docs.oasis-open.org/odata/ns/related/ProductDetail" type="application/atom+xml;type=entry" title="ProductDetail" href="Products(0)/ProductDetail"/>
    <title/>
    <updated>2015-05-19T03:38:50Z</updated>
    <author>
      <name/>
    </author>
    <content type="application/xml">
      <m:properties>
        <d:ID m:type="Int32">0</d:ID>
        <d:Name>Bread</d:Name>
        <d:Description>Whole grain bread</d:Description>
        <d:ReleaseDate m:type="DateTimeOffset">1992-01-01T00:00:00Z</d:ReleaseDate>
        <d:DiscontinuedDate m:null="true"/>
        <d:Rating m:type="Int16">4</d:Rating>
        <d:Price m:type="Double">2.5</d:Price>
      </m:properties>

  </entry>
  <entry>
    <id>http://services.odata.org/V4/OData/OData.svc/Products(1)</id>
    <category term="#ODataDemo.Product" scheme="http://docs.oasis-open.org/odata/ns/scheme"/>
    <link rel="edit" title="Product" href="Products(1)"/>
    <link rel="http://docs.oasis-open.org/odata/ns/relatedlinks/Categories" type="application/xml" title="Categories" href="Products(1)/Categories/$ref"/>
    <link rel="http://docs.oasis-open.org/odata/ns/related/Categories" type="application/atom+xml;type=feed" title="Categories" href="Products(1)/Categories"/>
    <link rel="http://docs.oasis-open.org/odata/ns/relatedlinks/Supplier" type="application/xml" title="Supplier" href="Products(1)/Supplier/$ref"/>
    <link rel="http://docs.oasis-open.org/odata/ns/related/Supplier" type="application/atom+xml;type=entry" title="Supplier" href="Products(1)/Supplier"/>
    <link rel="http://docs.oasis-open.org/odata/ns/relatedlinks/ProductDetail" type="application/xml" title="ProductDetail" href="Products(1)/ProductDetail/$ref"/>
    <link rel="http://docs.oasis-open.org/odata/ns/related/ProductDetail" type="application/atom+xml;type=entry" title="ProductDetail" href="Products(1)/ProductDetail"/>
    <title/>
    <updated>2015-05-19T03:38:50Z</updated>
    <author>
      <name/>
    </author>
    <content type="application/xml">
      <m:properties>
        <d:ID m:type="Int32">1</d:ID>
        <d:Name>Milk</d:Name>
        <d:Description>Low fat milk</d:Description>
        <d:ReleaseDate m:type="DateTimeOffset">1995-10-01T00:00:00Z</d:ReleaseDate>
        <d:DiscontinuedDate m:null="true"/>
        <d:Rating m:type="Int16">3</d:Rating>
        <d:Price m:type="Double">3.5</d:Price>
      </m:properties>

  </entry>
  ...
</feed>
```


#### OData 메타데이터 문서 샘플

```xml
<edmx:Edmx Version="4.0" xmlns:edmx="http://docs.oasis-open.org/odata/ns/edmx">
  <edmx:DataServices>
    <Schema Namespace="ODataDemo" xmlns="http://docs.oasis-open.org/odata/ns/edm">
      <EntityType Name="Product">
        <Key>
          <PropertyRef Name="ID"/>
        </Key>
        <Property Name="ID" Type="Edm.Int32" Nullable="false"/>
        <Property Name="Name" Type="Edm.String"/>
        <Property Name="Description" Type="Edm.String"/>
        <Property Name="ReleaseDate" Type="Edm.DateTimeOffset" Nullable="false"/>
        <Property Name="DiscontinuedDate" Type="Edm.DateTimeOffset"/>
        <Property Name="Rating" Type="Edm.Int16" Nullable="false"/>
        <Property Name="Price" Type="Edm.Double" Nullable="false"/>
      </EntityType>

      <ComplexType Name="Address">
        <Property Name="Street" Type="Edm.String"/>
        <Property Name="City" Type="Edm.String"/>
        <Property Name="State" Type="Edm.String"/>
        <Property Name="ZipCode" Type="Edm.String"/>
        <Property Name="Country" Type="Edm.String"/>
      </ComplexType>

      <EntityContainer Name="DemoService">
        <EntitySet Name="Products" EntityType="ODataDemo.Product"></EntitySet>
      </EntityContainer>
    </Schema>
  </edmx:DataServices>
</edmx:Edmx>
```


### 응용 프로그램
응용 프로그램에는 다음이 포함된다.
* 프로그레스 데이터다이렉트 하이브리드 데이터 파이프라인은 모든 클라우드, 빅 데이터 또는 관계형 데이터 소스를 OData 엔드포인트로 노출할 수 있다.
* 소크라타는 OData API를 노출한다.
* 마이크로소프트 애저는 OData API를 노출한다.
* 오라클 애널리틱스 클라우드는 OData API에 연결할 수 있다.
* SAP 넷위버 게이트웨이는 SAP Business Suite 및 SAP Business Warehouse에 OData 접근을 제공한다.
* IBM 웹스피어 익스트림 스케일 REST 데이터 서비스는 OData를 사용하는 모든 HTTP 클라이언트에서 접근할 수 있다.
* 마이크로소프트 셰어포인트 2010 이상 버전은 데이터를 OData 엔드포인트로 노출할 수 있다.
* Office 365는 OData V4.0 API를 노출한다.
* 세일즈포스 커넥트는 OData API를 소비한다.
* 스카이비아 커넥트는 OData를 통해 클라우드 및 데이터베이스 데이터를 노출한다.
* 태블로는 OData API에 연결할 수 있다.
* TIBCO 스팟파이어는 OData API에 연결할 수 있다.
* 뮬소프트는 OData API와 통합하는 데 도움을 준다.
* 석세스팩터스는 OData API를 사용한다.
* 세리디언 HCM의 데이포스는 Odata를 사용한다.
* 레드피시는 Odata를 사용한다.

## 도구
* 뉴클론 데이터베이스 마스터

## 같이 보기
* GData – 구글의 경쟁 프로토콜
* 자원 기술 프레임워크 (RDF) – W3C의 유사한 개념
* GraphQL - 페이스북/메타에서 유래한 인기 있는 프로토콜

## 각주

## 외부 링크
* 공식 웹사이트
* WCF로 서비스 지향 애플리케이션 개발
* OData 기본 프레젠테이션

분류:XML 기반 표준
분류:웹 신디케이션 형식
분류:ISO/IEC 표준