OData #1　触ってみる

　OData ( Open Data Protocol )は、Microsoftが2007年に始めた、REST APIを使ったデータ転送のためのWebプロトコルです。現在は、OASIS ( 構造化情報標準促進協会 )により標準化が行われています。
　表形式のデータを照会、編集、登録することができます。また、top、select、filterなどを使ってデータリクエストを定型化できます。
　利用できるサービスはおおくないのですが、Dynamics 365 Web APIや Office365 GraphAPI, SharePont REST, Salesforceで使用できます。

# ODataの書式

https://docs.microsoft.com/ja-jp/power-bi/connect-data/desktop-connect-odata

　Northwindのサンプルデータを取得します。
　ODataは、XML形式で記述されています。

**https://services.odata.org/v2/northwind/northwind.svc/**
```xml:Northwind
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<service xml:base="https://services.odata.org/V2/Northwind/Northwind.svc/" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:app="http://www.w3.org/2007/app" xmlns="http://www.w3.org/2007/app">
  <workspace>
    <atom:title>Default</atom:title>
    <collection href="Categories">
      <atom:title>Categories</atom:title>
    </collection>
    <collection href="CustomerDemographics">
      <atom:title>CustomerDemographics</atom:title>
    </collection>
    <collection href="Customers">
      <atom:title>Customers</atom:title>
    </collection>
    <collection href="Employees">
      <atom:title>Employees</atom:title>
    </collection>
    <collection href="Order_Details">
      <atom:title>Order_Details</atom:title>
    </collection>
 ....
```

　最初に、service の xml:base が問い合わせ先のルートurlになります。そのあとのcollectionにはCategoriesやCustomersなどのテーブル（エンティティ）のリンク先が書かれています。

# テーブルの定義 $metadata
　テーブルの定義については、**$metadata** を開くと表示されます。

**https://services.odata.org/v2/northwind/northwind.svc/$metadata**
```xml:metadata
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<edmx:Edmx Version="1.0" xmlns:edmx="http://schemas.microsoft.com/ado/2007/06/edmx">
  <edmx:DataServices xmlns:m="http://schemas.microsoft.com/ado/2007/08/dataservices/metadata" m:DataServiceVersion="1.0">
    <Schema Namespace="NorthwindModel" xmlns:d="http://schemas.microsoft.com/ado/2007/08/dataservices" xmlns:m="http://schemas.microsoft.com/ado/2007/08/dataservices/metadata" xmlns="http://schemas.microsoft.com/ado/2008/09/edm">

.....

      <EntityType Name="Customer">
        <Key>
          <PropertyRef Name="CustomerID" />
        </Key>
        <Property Name="CustomerID" Type="Edm.String" Nullable="false" MaxLength="5" Unicode="true" FixedLength="true" />
        <Property Name="CompanyName" Type="Edm.String" Nullable="false" MaxLength="40" Unicode="true" FixedLength="false" />
        <Property Name="ContactName" Type="Edm.String" Nullable="true" MaxLength="30" Unicode="true" FixedLength="false" />
        <Property Name="ContactTitle" Type="Edm.String" Nullable="true" MaxLength="30" Unicode="true" FixedLength="false" />
        <Property Name="Address" Type="Edm.String" Nullable="true" MaxLength="60" Unicode="true" FixedLength="false" />
        <Property Name="City" Type="Edm.String" Nullable="true" MaxLength="15" Unicode="true" FixedLength="false" />
        <Property Name="Region" Type="Edm.String" Nullable="true" MaxLength="15" Unicode="true" FixedLength="false" />
        <Property Name="PostalCode" Type="Edm.String" Nullable="true" MaxLength="10" Unicode="true" FixedLength="false" />
        <Property Name="Country" Type="Edm.String" Nullable="true" MaxLength="15" Unicode="true" FixedLength="false" />
        <Property Name="Phone" Type="Edm.String" Nullable="true" MaxLength="24" Unicode="true" FixedLength="false" />
        <Property Name="Fax" Type="Edm.String" Nullable="true" MaxLength="24" Unicode="true" FixedLength="false" />
        <NavigationProperty Name="Orders" Relationship="NorthwindModel.FK_Orders_Customers" FromRole="Customers" ToRole="Orders" />
        <NavigationProperty Name="CustomerDemographics" Relationship="NorthwindModel.CustomerCustomerDemo" FromRole="Customers" ToRole="CustomerDemographics" />
      </EntityType>
      <EntityType Name="Employee">
.....
      <Association Name="FK_Orders_Customers">
        <End Role="Customers" Type="NorthwindModel.Customer" Multiplicity="0..1" />
        <End Role="Orders" Type="NorthwindModel.Order" Multiplicity="*" />
        <ReferentialConstraint>
          <Principal Role="Customers">
            <PropertyRef Name="CustomerID" />
          </Principal>
          <Dependent Role="Orders">
            <PropertyRef Name="CustomerID" />
          </Dependent>
        </ReferentialConstraint>
      </Association>
.....
```
　Customerテーブル（エンティティ）には、CustomerIDというキーがあり、CustomerID、CompanyName、ContactNameなどの項目を持っており、OrdersとCustomerDemographicsにリレーションを持ってることがわかります。Associationでは、テーブル同士の関係を定義しています。

　Customerのデータを取得するには https://services.odata.org/v2/northwind/northwind.svc/Customers をブラウザで開くと以下のような顧客データが表示されます。

```xml:Customers
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<feed xml:base="https://services.odata.org/V2/Northwind/Northwind.svc/" xmlns:d="http://schemas.microsoft.com/ado/2007/08/dataservices" xmlns:m="http://schemas.microsoft.com/ado/2007/08/dataservices/metadata" xmlns="http://www.w3.org/2005/Atom">
  <title type="text">Customers</title>
  <id>https://services.odata.org/v2/northwind/northwind.svc/Customers</id>
  <updated>2022-02-27T22:22:37Z</updated>
  <link rel="self" title="Customers" href="Customers" />
  <entry>
    <id>https://services.odata.org/V2/Northwind/Northwind.svc/Customers('ALFKI')</id>
    <title type="text"></title>
    <updated>2022-02-27T22:22:37Z</updated>
    <author>
      <name />
    </author>
    <link rel="edit" title="Customer" href="Customers('ALFKI')" />
    <link rel="http://schemas.microsoft.com/ado/2007/08/dataservices/related/Orders" type="application/atom+xml;type=feed" title="Orders" href="Customers('ALFKI')/Orders" />
    <link rel="http://schemas.microsoft.com/ado/2007/08/dataservices/related/CustomerDemographics" type="application/atom+xml;type=feed" title="CustomerDemographics" href="Customers('ALFKI')/CustomerDemographics" />
    <category term="NorthwindModel.Customer" scheme="http://schemas.microsoft.com/ado/2007/08/dataservices/scheme" />
    <content type="application/xml">
      <m:properties>
        <d:CustomerID m:type="Edm.String">ALFKI</d:CustomerID>
        <d:CompanyName m:type="Edm.String">Alfreds Futterkiste</d:CompanyName>
        <d:ContactName m:type="Edm.String">Maria Anders</d:ContactName>
        <d:ContactTitle m:type="Edm.String">Sales Representative</d:ContactTitle>
        <d:Address m:type="Edm.String">Obere Str. 57</d:Address>
        <d:City m:type="Edm.String">Berlin</d:City>
        <d:Region m:type="Edm.String" m:null="true" />
        <d:PostalCode m:type="Edm.String">12209</d:PostalCode>
        <d:Country m:type="Edm.String">Germany</d:Country>
        <d:Phone m:type="Edm.String">030-0074321</d:Phone>
        <d:Fax m:type="Edm.String">030-0076545</d:Fax>
      </m:properties>
    </content>
  </entry>
.....
```
　ここではxml形式で表示されていますが、サービスによってはjsonで帰ってくることもあります。


# 件数表示 $count
　件数は $count で調べます。

```
https://services.odata.org/v2/northwind/northwind.svc/Orders/$count
```
　結果は830件でした。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/864075/0fab2724-7e90-3452-e6b8-a6b3d101966d.png)


# 行の選択 $filter, $top, $skip
　Productsのデータを選択する方法は、以下のようにすることもできます。

```xml
https://services.odata.org/v2/northwind/northwind.svc/Orders?$filter=OrderID eq 10248&$format=json

or

https://services.odata.org/v2/northwind/northwind.svc/Orders(10248)?$format=json
```


```json
{
   "d":{
      "results":[
         {
            "__metadata":{
               "uri":"https://services.odata.org/V2/Northwind/Northwind.svc/Orders(10248)",
               "type":"NorthwindModel.Order"
            },
            "OrderID":10248,
            "CustomerID":"VINET",
            "EmployeeID":5,
            "OrderDate":"\/Date(836438400000)\/",
            "RequiredDate":"\/Date(838857600000)\/",
            "ShippedDate":"\/Date(837475200000)\/",
            "ShipVia":3,
            "Freight":"32.3800",
            "ShipName":"Vins et alcools Chevalier",
            "ShipAddress":"59 rue de l'Abbaye",
            "ShipCity":"Reims",
            "ShipRegion":null,
            "ShipPostalCode":"51100",
            "ShipCountry":"France",
            "Customer":{
               "__deferred":{
                  "uri":"https://services.odata.org/V2/Northwind/Northwind.svc/Orders(10248)/Customer"
               }
            },
            "Employee":{
               "__deferred":{
                  "uri":"https://services.odata.org/V2/Northwind/Northwind.svc/Orders(10248)/Employee"
               }
            },
            "Order_Details":{
               "__deferred":{
                  "uri":"https://services.odata.org/V2/Northwind/Northwind.svc/Orders(10248)/Order_Details"
               }
            },
            "Shipper":{
               "__deferred":{
                  "uri":"https://services.odata.org/V2/Northwind/Northwind.svc/Orders(10248)/Shipper"
               }
            }
         }
      ]
   }
}
```

https://docs.microsoft.com/ja-jp/azure/search/search-query-odata-filter


# 列の選択 $select
　表示する項目を選択するには $select を使用します。

```xml
https://services.odata.org/v2/northwind/northwind.svc/Orders?$select=OrderID,OrderDate,ShipCountry&$top=3&$format=json
```

```json
{
  "d": [
    {
      "__metadata": {
        "uri": "https://services.odata.org/V2/Northwind/Northwind.svc/Orders(10248)",
        "type": "NorthwindModel.Order"
      },
      "OrderID": 10248,
      "OrderDate": "/Date(836438400000)/",
      "ShipCountry": "France"
    },
    {
      "__metadata": {
        "uri": "https://services.odata.org/V2/Northwind/Northwind.svc/Orders(10249)",
        "type": "NorthwindModel.Order"
      },
      "OrderID": 10249,
      "OrderDate": "/Date(836524800000)/",
      "ShipCountry": "Germany"
    },
    {
      "__metadata": {
        "uri": "https://services.odata.org/V2/Northwind/Northwind.svc/Orders(10250)",
        "type": "NorthwindModel.Order"
      },
      "OrderID": 10250,
      "OrderDate": "/Date(836784000000)/",
      "ShipCountry": "Brazil"
    }
  ]
}
```