acumatica
REST契約ベースのAPIによるレコードのエクスポート
サーチ…
前書き
このトピックでは、Acumatica ERPからREST Contract-Based APIを使用してレコードをエクスポートする方法を説明します。 Acumatica ERPのScreen-Based APIとは対照的に、Contract-Based APIはSOAPインタフェースとRESTインタフェースの両方を提供します。契約ベースのAPIの詳細については、 Acumatica ERPのドキュメントを参照してください。
備考
Acumatica ERPのREST Contract-Based APIと通信するには、クライアントアプリケーションは常に次の3つのステップを実行する必要があります。
Acumatica ERPインスタンスにログインし、ユーザーセッション情報でCookieを取得する
Acumatica ERPインスタンスで利用可能な契約ベースのAPIエンドポイントの1つと対話する
Acumatica ERPからログアウトしてユーザセッションを終了する
このトピックで提供されるすべてのサンプルは、標準のAcumatica ERPインストールプロセスの一部として常に配置されるDefaultエンドポイントで構築されています。 Webサービスエンドポイント画面(SM.20.70.60)では、既存のエンドポイントの詳細を表示したり、Acumatica ERP契約ベースのWebサービスのカスタムエンドポイントを設定することができます。
参考までに、Acumatica ERPの契約ベースのWebサービスと対話するために上記のすべてのサンプルで使用されているRestServiceクラスの実装を以下に示します。
public class RestService : IDisposable
{
private readonly HttpClient _httpClient;
private readonly string _acumaticaBaseUrl;
private readonly string _acumaticaEndpointUrl;
public RestService(string acumaticaBaseUrl, string endpoint,
string userName, string password,
string company, string branch)
{
_acumaticaBaseUrl = acumaticaBaseUrl;
_acumaticaEndpointUrl = _acumaticaBaseUrl + "/entity/" + endpoint + "/";
_httpClient = new HttpClient(
new HttpClientHandler
{
UseCookies = true,
CookieContainer = new CookieContainer()
})
{
BaseAddress = new Uri(_acumaticaEndpointUrl),
DefaultRequestHeaders =
{
Accept = {MediaTypeWithQualityHeaderValue.Parse("text/json")}
}
};
var str = new StringContent(
new JavaScriptSerializer()
.Serialize(
new
{
name = userName,
password = password,
company = company,
branch = branch
}),
Encoding.UTF8, "application/json");
_httpClient.PostAsync(acumaticaBaseUrl + "/entity/auth/login", str)
.Result.EnsureSuccessStatusCode();
}
void IDisposable.Dispose()
{
_httpClient.PostAsync(_acumaticaBaseUrl + "/entity/auth/logout",
new ByteArrayContent(new byte[0])).Wait();
_httpClient.Dispose();
}
public string GetList(string entityName)
{
var res = _httpClient.GetAsync(_acumaticaEndpointUrl + entityName)
.Result.EnsureSuccessStatusCode();
return res.Content.ReadAsStringAsync().Result;
}
public string GetList(string entityName, string parameters)
{
var res = _httpClient.GetAsync(_acumaticaEndpointUrl + entityName + "?" + parameters)
.Result.EnsureSuccessStatusCode();
return res.Content.ReadAsStringAsync().Result;
}
}
1回のRESTコールでのデータエクスポート
この例では、REST Contract-Based APIを使用してAcumatica ERPから以下のデータを1回の呼び出しでエクスポートする方法を探ります:
- アプリケーションに存在するすべての在庫アイテム
- INタイプのすべての受注
Acumatica ERPからレコードをエクスポートする必要がある場合は、 http://<Acumatica ERP instance URL>/entity/<Endpoint name>/<Endpoint version>/<Top-level entity>
<Top-level entity>
は、エクスポートしようとしているエンティティの名前です
1回のREST呼び出しですべての在庫アイテムをエクスポートするには:
バージョン6.00.001の デフォルトエンドポイントを使用してローカルAcumaticaERP
インスタンスから在庫アイテムレコードをエクスポートするには、 http://localhost/AcumaticaERP/entity/Default/6.00.001/StockItem
使用する必要があります。
以下は、バージョン6.00.001の デフォルトエンドポイントに単一のREST呼び出しを送信することによって、すべてのストックアイテムをエクスポートするためにC#で書かれたサンプルコードです。
using (RestService rs = new RestService(
@"http://localhost/AcumaticaERP/", "Default/6.00.001",
username, password, company, branch))
{
string stockItems = rs.GetList("StockItem");
}
1回のREST呼び出しでINタイプのすべての受注をエクスポートするには、次のようにします。
バージョン6.00.001の デフォルトエンドポイントを使用してローカルAcumaticaERP
インスタンスからINタイプの受注をエクスポートするには、 http://localhost/AcumaticaERP/entity/Default/6.00.001/SalesOrder?$filter=OrderType eq 'IN'
以下は、バージョン6.00.001の デフォルトエンドポイントに1回のREST呼び出しを送信することによって、 INタイプのすべての受注をエクスポートするためにC#で書かれたサンプルコードです。
using (RestService rs = new RestService(
@"http://localhost/StackOverflow/", "Default/6.00.001",
username, password, company, branch))
{
var parameters = "$filter=OrderType eq 'IN'";
string inSalesOrders = rs.GetList("SalesOrder", parameters);
}
複数のREST要求に対するページネーションの実装
この例では、Acumatica ERPからREST Contract-Based APIを介してバッチで以下のデータをエクスポートする方法を探ります:
- 10レコードのバッチでアプリケーションに存在する在庫アイテム
- すべての受注は100レコードのバッチで
複数のREST呼び出しで在庫アイテムを10レコードのバッチでエクスポートするには:
バージョン6.00.001の デフォルトエンドポイントを使用してローカルのAcumaticaERP
インスタンスから最初の10個の在庫アイテムをエクスポートするには、 http://localhost/AcumaticaERP/entity/Default/6.00.001/StockItem?$top=10
したがって、在庫アイテムを10から20にリクエストするには、上記のURLをフィルタパラメータhttp://localhost/AcumaticaERP/entity/Default/6.00.001/StockItem?$top=10&$filter=InventoryID gt '<InventoryID>'
<InventoryID>
は、直前のREST呼び出しでエクスポートされた最後の在庫アイテムのIDです
以下は、バージョン6.00.001の デフォルトエンドポイントに複数のREST呼び出しを送信して、10レコードのバッチですべての在庫アイテムをエクスポートするためにC#で書かれたサンプルコードです。
using (RestService rs = new RestService(
@"http://localhost/StackOverflow/", "Default/6.00.001",
username, password, company, branch))
{
var json = new JavaScriptSerializer();
string parameters = "$top=10";
string items = rs.GetList("StockItem", parameters);
var records = json.Deserialize<List<Dictionary<string, object>>>(items);
while (records.Count == 10)
{
var inventoryID = records[records.Count - 1]["InventoryID"] as Dictionary<string, object>;
var inventoryIDValue = inventoryID.Values.First();
string nextParameters = parameters + "&" +
"$filter=" + string.Format("InventoryID gt '{0}'", inventoryIDValue);
items = rs.GetList("StockItem", nextParameters);
records = json.Deserialize<List<Dictionary<string, object>>>(items);
}
}
複数のREST呼び出しを含む100レコードのバッチですべての受注をエクスポートするには、次のようにします。
バージョン6.00.001の デフォルトエンドポイントを使用してローカルのAcumaticaERP
インスタンスから最初の100件の受注をエクスポートするには、 http://localhost/AcumaticaERP/entity/Default/6.00.001/SalesOrder?$top=100
受注エンティティの主キーは注文タイプと注文番号で構成されているため、この例では、 注文タイプフィールドと注文番号フィールドにフィルタパラメータの組み合わせを使用します。
- SOタイプの100から200の受注をリクエストするには、
http://localhost/AcumaticaERP/entity/Default/6.00.001/SalesOrder?$top=100&$filter=OrderType eq 'SO' and OrderNbr gt '<OrderNbr>'
<OrderNbr>
は、以前のREST呼び出しでエクスポートされた最後の受注の番号です
- したがって、 SOタイプの最初の100件の受注をリクエストするには、
http://localhost/AcumaticaERP/entity/Default/6.00.001/SalesOrder?$top=100&$filter=OrderType gt 'SO' and OrderNbr gt ''
以下は、C#で書かれたサンプルコードで、すべての受注を複数のREST呼び出しを伴う100レコードのバッチで、バージョン6.00.001の デフォルトエンドポイントにエクスポートします。
using (RestService rs = new RestService(
@"http://localhost/StackOverflow/", "Default/6.00.001",
username, password, company, branch))
{
var json = new JavaScriptSerializer();
string parameters = "$top=100";
string items = rs.GetList("SalesOrder", parameters);
var records = json.Deserialize<List<Dictionary<string, object>>>(items);
bool sameOrderType = true;
while (records.Count > 0 && (records.Count == 100 || !sameOrderType))
{
var orderType = records[records.Count - 1]["OrderType"] as Dictionary<string, object>;
var orderTypeValue = orderType.Values.First();
var orderNbr = records[records.Count - 1]["OrderNbr"] as Dictionary<string, object>;
var orderNbrValue = orderNbr.Values.First();
string nextParameters = parameters + "&" + "$filter=" +
string.Format("OrderType {0} '{1}'", sameOrderType ? "eq" : "gt", orderTypeValue) + " and " +
string.Format("OrderNbr gt '{0}'", sameOrderType ? orderNbrValue : "''" );
items = rs.GetList("SalesOrder", nextParameters);
records = json.Deserialize<List<Dictionary<string, object>>>(items);
sameOrderType = records.Count == 100;
}
}