Morning Girl

Web API, Windows, C#, .NET, Dynamics 365/CRM etc..

Java クライント開発における Web API の実装アプローチ:その3 Swagger(OpenAPI)Code Generate 編

f:id:sugimomoto:20190121012241p:plain

前回は シンプルな REST API 実装をお送りしました。

今回は、前回見えてきた課題点も踏まえながら、Swagger(OpenAPI)を利用した Web API実装アプローチを見ていきます。

最初の記事はこちらから。

bit.ly

Swagger(OpenAPI)って何?

swagger.io

その前に少しだけ、Swagger(OpenAPI)に触れておきます。Gtihub の「The OpenAPI Specification」では、以下のように記載があります。

OpenAPI Specification(OAS)は、ソースコードへのアクセス、追加ドキュメント、またはネットワークトラフィックの検査を必要とせずに、人間とコンピュータの両方がサービスの機能を発見して理解することを可能にする、  プログラミング言語に依存しないREST APIの標準的なインターフェイス記述を定義します。

引用元:https://github.com/OAI/OpenAPI-Specification

ここで一つポイントとなるのは REST API の記述用言語とそれに伴うエコシステム全体を指すということです。

ベースとなる考えは、REST API の仕様(URLパラメータや認証方式、HTTPメソッドは何を使うのか、レスポンスの仕様、JSON構造はどうなっているのか?等)を記述するための仕様であるということ。

以下のよなYAML(もしくはJSON ベース)でその仕様を記述します。

paths:
  /categories:
    get:
      summary: Return categories
      description: >-
        Returns records from the categories entity that match the specified
        query parameters.  All records will be returned when no parameters are
        specified.
      tags:
        - categories
      operationId: getAllcategories
      parameters:
        - name: $select
          in: query
          type: string
          description: >-
            A comma-separated list of properties to include in the results. When
            this field is left empty, all properties will be returned.
        - name: $orderby
          in: query
          type: string
          description: >-
            Order the results by this property in ascending or descending
            order.  Example for ascending: 'Name ASC' Example for descending:
            'Name DESC'
        - name: $top
          in: query
          type: integer
          description: The number of results to return.
        - name: $skip
          in: query
          type: integer
          description: This is the offset of results to skip when returning results.
        - name: $count
          in: query
          type: boolean
          description: >-
            When set, the results will return a count of results and not the
            actual results.
        - name: $filter
          in: query
          type: string
          description: >-
            Use this to filter the results by specific property values. For
            example, you can use the following filter to retrieve records with
            the name 'John': $filter=Name eq 'John'
      responses:
        '200':
          description: categories response
          schema:
            type: object
            properties:
              value:
                type: array
                items:
                  $ref: '#/definitions/categories'

この仕様があるおかげで、Swagger エコシステムでは、API ドキュメントの自動生成やテスト・ライブラリの生成などを実現することが可能になっています。

f:id:sugimomoto:20190120122040p:plain

SOAP では WSDLJSONだとJSON スキーマなどの仕様記述様式がありますが、そのREST 版であると捉えると、わかりやすいかなと。

OpenAPI(Swagger)で公開されているサービス

OData や GraphQL は日本でまだまだ馴染みが薄いですが、Swagger は結構人気な気がしますね。

国産クラウドサービスですと、「freee」や「CloudSign」「SmartHR」など

・freee:https://developer.freee.co.jp/docs/accounting/reference

・CloudSign:https://app.swaggerhub.com/apis/CloudSign/cloudsign-web_api/0.8.0

・SmartHR:https://developer.smarthr.jp/api/index.html

また、SendgridもSwaggerベースでドキュメントが公開されています。

・Sendgrid https://github.com/sendgrid/sendgrid-oai

その他、API Spec系

ちなみに、他にもAPI Spec系のサービス・仕様はありますが、トレンドの状況を見るとほぼ Swagger 一強かなと感じます。

・RAML https://raml.org/

・apiary.io https://apiary.io/

JSON Schema https://json-schema.org/

API Blueprint https://apiblueprint.org/

f:id:sugimomoto:20190120122051p:plain

対象の API

f:id:sugimomoto:20190120000738p:plain

対象の API は前回と一緒です。同じようにODataベースの REST API ではありますが、今回は Swagger(OpenAPI)でドキュメントが公開されている、ということを前提に進めます。

https://app.swaggerhub.com/apis/sugimomoto/CDataNorthWindSample/1.0.0

操作も同じように注文データ(orders)と注文明細データ(order_details)を取得して結合したものをコンソールで出力するというものです。

Client SDK の Code Generate

それでは、まず今回のキモとなる Client SDK Generateを行います。

SwaggerHub の API ドキュメント画面にアクセスすると、画面右上に「Export」ボタンがあります。

ここから、Server Side の Mock や Client SDK をダウンロードすることができます。

f:id:sugimomoto:20190120122101p:plain

以下のようなフォルダーが生成されます。デフォルトで Marven の pom.xml などが含まれているので、

f:id:sugimomoto:20190120122108p:plain

そのまま IntelliJ IDEA などでプロジェクトとしてインポートできます。

f:id:sugimomoto:20190120122113p:plain

プロジェクトを展開して、まずポイントとなる部分だけみてみましょう。

「package io.swagger.client.api」には、各エンドポイントのAPI 実行のコントロールを行うためのClientクラス郡が入っています。

f:id:sugimomoto:20190120122119p:plain

「package io.swagger.client.model;」には、取得できるJSON Objesをシリアライズ・デシリアライズするための Class が自動生成されていることがわかります。

このあたりを全部自動生成してくれるのが、素晴らしい!

f:id:sugimomoto:20190120122128p:plain

また、Test フォルダを覗くと、各エンドポイントの網羅的なテスト用のベースになる Class も自動生成されていることがわかります。

これらも Swagger Spec をベースに生成されるので楽ですね。

f:id:sugimomoto:20190120122138p:plain

「README.MD」ファイルには、Getting Started として、最初にリクエストを実施するためのサンプルコードも記載されていますので、使い方を把握するのも結構楽ちん。

[ Getting Started ]

Please follow the installation instruction and execute the following Java code:

import io.swagger.client.*;
import io.swagger.client.auth.*;
import io.swagger.client.model.*;
import io.swagger.client.api.CategoriesApi;

import java.io.File;
import java.util.*;

public class CategoriesApiExample {

    public static void main(String[] args) {
        ApiClient defaultClient = Configuration.getDefaultApiClient();
        
        // Configure API key authorization: authtoken_header
        ApiKeyAuth authtoken_header = (ApiKeyAuth) defaultClient.getAuthentication("authtoken_header");
        authtoken_header.setApiKey("YOUR API KEY");
        // Uncomment the following line to set a prefix for the API key, e.g. "Token" (defaults to null)
        //authtoken_header.setApiKeyPrefix("Token");

        // Configure API key authorization: authtoken_query
        ApiKeyAuth authtoken_query = (ApiKeyAuth) defaultClient.getAuthentication("authtoken_query");
        authtoken_query.setApiKey("YOUR API KEY");
        // Uncomment the following line to set a prefix for the API key, e.g. "Token" (defaults to null)
        //authtoken_query.setApiKeyPrefix("Token");

        // Configure HTTP basic authorization: basic
        HttpBasicAuth basic = (HttpBasicAuth) defaultClient.getAuthentication("basic");
        basic.setUsername("YOUR USERNAME");
        basic.setPassword("YOUR PASSWORD");

        CategoriesApi apiInstance = new CategoriesApi();
        Categories categories = new Categories(); // Categories | The categories entity to post
        try {
            Categories result = apiInstance.createcategories(categories);
            System.out.println(result);
        } catch (ApiException e) {
            System.err.println("Exception when calling CategoriesApi#createcategories");
            e.printStackTrace();
        }
    }
}

それでは、実際に実装を進めていきます。

実装コード

gist.github.com

Java クライアントアプリケーションから Swagger Client SDK を利用するにあたってのポイント

前回投稿した HTTP Client を実装してアプローチする場合に比べて、だいぶスッキリしたと思います。

認証周りや接続設定はApiClientをベースに、各 Swagger Specで定義されているパラメータが setpropertyName 形式で生成され、提供されているのでわかりやすいですね。

    ApiClient defaultClient = Configuration.getDefaultApiClient();
    defaultClient.setApiKey("XXXXXXXXXXX");

また、実査しにOrdersなどを取得する際に使っている getAllorders のメソッドの引数もポイントです。

以下のように、「String select, String orderby, Integer top, Integer skip, Boolean count, String filter」と6種類の引数が提供されているのですが、

    /**
     * Return orders
     * Returns records from the orders entity that match the specified query parameters.  All records will be returned when no parameters are specified.
     * @param select A comma-separated list of properties to include in the results. When this field is left empty, all properties will be returned. (optional)
     * @param orderby Order the results by this property in ascending or descending order.  Example for ascending: 'Name ASC' Example for descending: 'Name DESC' (optional)
     * @param top The number of results to return. (optional)
     * @param skip This is the offset of results to skip when returning results. (optional)
     * @param count When set, the results will return a count of results and not the actual results. (optional)
     * @param filter Use this to filter the results by specific property values. For example, you can use the following filter to retrieve records with the name 'John': $filter=Name eq 'John' (optional)
     * @return InlineResponse2004
     * @throws ApiException If fail to call the API, e.g. server error or cannot deserialize the response body
     */
    public InlineResponse2004 getAllorders(String select, String orderby, Integer top, Integer skip, Boolean count, String filter) throws ApiException {
        ApiResponse<InlineResponse2004> resp = getAllordersWithHttpInfo(select, orderby, top, skip, count, filter);
        return resp.getData();
    }

これはそのまま対象エンドポイントの URLパラメータ にマッチングされています。

https://app.swaggerhub.com/apis/sugimomoto/c-data_swagger_api_sample/1.0.0#/orders/getAllorders

f:id:sugimomoto:20190120122700p:plain

今回は OData をベースにしているため、とても素直な URL パラメータですが、それでも HTTP Client ベースで実装した場合のURL パラメータ組み立ての実装コードを一から書かなくてもいいと言うのは、やはりとても楽だなと思います。

おわりに

こうやって実際に実装コードベースで見ていくと、REST API を頑張って実装するのに比べてずいぶん省力化してできるなぁというのが、自分自身よく実感できました。

また、Web API を使う場合、実際の HTTP ベースでリクエストを行うモデルレイヤーだけでなく、最終的なビジネスロジック部分の記述のほうが重要性が高いわけですし、こういったところで省力化できるのはプロジェクト全体にとっても重要な部分だと思います。

それでは、次回は若干毛色を変えて、OData ベースでの実装を見ていきたいと思います。

Java クライント開発における Web API の実装アプローチ:その2 一般的なREST API編

それでは、今回から実際にそれぞれのWeb APIリクエストの実装アプローチを見ていきたいと思います。

最初はベーシックかつ、ふんわりとした取り決めである REST API から。

最初の記事はこちらから。

bit.ly

RESTについておさらい

f:id:sugimomoto:20190119235236p:plain

ここではあまり多く語りませんが、REST はプロトコルや規約ではなく、あくまで Web API の設計思想、ソフトウェアアーキテクチャの一つであるという点です。

REST = Representational State Transfer

Representational State Transfer (REST) は、ウェブのような分散ハイパーメディアシステムのためのソフトウェアアーキテクチャのスタイルのひとつである。

引用元:Wikipedia REST

ja.wikipedia.org

以下の4つの原則に従った Web API アーキテクチャをREST ful と呼んだりしますね。

Stateless:ステートレスなクライアント/サーバプロトコル
    
Uniform Interface:すべての情報(リソース)に適用できるHTTPメソッドの定義
    
Addressability:リソースを一意に識別する「汎用的な構文(URL)」の定義
    
Connectability:アプリケーションの情報と状態遷移の両方を扱うことができる「ハイパーメディア(リソースリンク)の使用」

ただ、今回の記事では REST の原則には従っているが、それ以外の仕様に準拠しているわけではない、普遍的かつドキュメント以上のものが提供されていない Web API のことを示すこととしています。(これは別に REST を卑下しているわけではなく、今後のAPIスタイルとの比較のためです)

対象の REST API と前提条件

f:id:sugimomoto:20190122182734p:plain

対象とする Web API は CData API Server を使って開発したものを利用します。

app.swaggerhub.com

ODataプロトコルベースで、Swagger(OpenAPI)ドキュメントを公開していますが、特に今回は OData や Swagger であることを意識しません。

あくまでドキュメント以上のものは無い(SDKなども含めて)、という前提に立ちます。

ですので、シンプルに Javaオープンソースライブラリを使ってアクセスします。

APIアクセス用のトークンは、要望があれば公開する予定です。

操作はシンプルに注文データ(orders)と注文明細データ(order_details)を取得して結合したものをコンソールで出力するというものです。

利用ライブラリ

Java から API へのアクセスについては「OkHttpClient」と「GSON」、2つのライブラリを使用しました。

・OkHttpClient

・GSON

実装コード

以下のサイトで公開しています。

github.com

package com.company;

import com.google.gson.Gson;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;

import java.util.List;
import java.util.stream.Collector;
import java.util.stream.Collectors;

public class Main {

  public static final String url = "http://cdatanorthwindsampleapiserver.azurewebsites.net/api.rsc/";
  public static final String categories = "categories";
  public static final String orders = "orders";
  public static final String order_details = "order_details";
  public static final String products = "products";

  public static final String authHeaderName = "x-cdata-authtoken";
  public static final String authHeaderValue = "XXXXXXXXXXX";

  public static void main(String[] args) throws Exception {

        OkHttpClient client = new OkHttpClient();

        Response ordersResponse = client.newCall(
                new Request.Builder().addHeader(authHeaderName,authHeaderValue).url(url + orders).build()
                ).execute();

        Response orderDetailsResponse = client.newCall(
                new Request.Builder().addHeader(authHeaderName,authHeaderValue).url(url + order_details).build()
                ).execute();

        Gson gson = new Gson();

        OrderRootObject orders = gson.fromJson(ordersResponse.body().string(), OrderRootObject.class);
        OrderDetailRootObject orderDetails = gson.fromJson(orderDetailsResponse.body().string(), OrderDetailRootObject.class);

        for (OrderDetail orderDetail : orderDetails.Value) {
            List<Order> order = orders.Value.stream().filter(x -> x.OrderId.equals(orderDetail.OrderId)).collect(Collectors.toList());

            if(order.isEmpty())
              continue;

            System.out.println("--------------------------------------------");
            System.out.println("OrderId : " + order.get(0).OrderId);
            System.out.println("CustomerId : " + order.get(0).CustomerId);
            System.out.println("EmployeeId : " + order.get(0).EmployeeId);
            System.out.println("Discount : " + orderDetail.Discount);
            System.out.println("ProductId : " + orderDetail.ProductId);
            System.out.println("Quantity : " + orderDetail.Quantity);
            System.out.println("UnitPrice : " + orderDetail.UnitPrice);
        }
    }
}

Java クライアントアプリケーションから REST API を利用するにあたってのポイント

実装は至ってシンプルにOkHttpClient を使って、Getリクエストしています。

OkHttpClient client = new OkHttpClient();

Response ordersResponse = client.newCall(
                new Request.Builder().addHeader(authHeaderName,authHeaderValue).url(url + orders).build()
                ).execute();

そして、JSONを使って、対象クラスへデシリアライズしますが、

Gson gson = new Gson();

OrderRootObject orders = gson.fromJson(ordersResponse.body().string(), OrderRootObject.class);

ちょっと面倒なのがデシリアライズ先のクラス作成です。

このくらいのカラム数ならそこまで面倒ではありませんが、ドキュメントから一つ一つ型などをチェックして、作成しなければいけません。

CData.WebAPI.JavaConsole.StandardRequest/Order.java at master · sugimomoto/CData.WebAPI.JavaConsole.StandardRequest · GitHub

package com.company;

import com.google.gson.annotations.SerializedName;

public class Order {

  @SerializedName("order_id")
  public String OrderId;

  @SerializedName("customer_id")
  public String CustomerId;

  @SerializedName("employee_id")
  public String EmployeeId;
}

JSONをベースにクラスを生成するツールなどもありますが、どこまでのJSONを対応させるのか? 動的にJSONのカラムが変わる場合などの考慮を考えると、面倒なシチュエーションも多いです。

もちろん、シンプルな REST API であれば、これで十分かなとは思いますが、これに加えてビジネスロジックも記述していくとなると、モデル部分としてはやや脆弱な部分があるのは否めないかなと思います。

また、今回は単純なリソース指定のみのリクエストでしたが、URLパラメータをどうするか、ページング処理などもどのように実装するかはドキュメントから一つ一つ読み取って実装していかないといけないのが、なかなか大変なところかと思います。

おわりに

単純に REST API を実装するだけでも、ドキュメントだけだとなかなか心許ない部分が見えてくるかなと思います。

次回はそんな部分を踏まえながら、OpenAPI(Swagger) ベースの実装を紹介します。

CData API Server で REST ful APIを作って、SwaggerHub でさくっと API ドキュメントを公開する

f:id:sugimomoto:20190119212039p:plain

CData API Server では、さくっと REST Ful な Web API 開発ができるのですが、APIを生成するともれなくSwagger Spec のエンドポイントがついてきます。

そこで、ドキュメントの見やすさや Code Generate などのエコシステムが強力なSwagger(OpenAPI)を、CData API Server を使いながら、さくっとSwagger Hub で公開してみたいと思います。

SwaggerHub って?

SwaggerHub は OpenAPI(Swagger)による API 開発を行うための Spec Editor や Code Generator、Document 機能を備えたクラウドサービスです。

f:id:sugimomoto:20190119212047p:plain

swagger.io

通常 オープンソースで提供されている一連の Swagger アプリケーションセットをサービス化したもの、言えばわかりやすいかもしれません。

そもそも Swagger って何? という方はこちらのドキュメントがわかりやすいと思います。

news.mynavi.jp

news.mynavi.jp

CData API Server の構成

CData API Server は以下のURLからトライアルの取得が可能です。

今回はAzure Web Apps上に構成して、Swagger Hubと連携できるようにしてみました。データベースは適当なサンプルDBを使って、エンドポイントを構成しています。

Azure Web Appsへのデプロイ方法は以下の記事をどうぞ。

http://kageura.hatenadiary.jp/entry/2017/11/27/Azure_SQL_Database%E3%82%92CData_API_Server%E3%81%A7Web_API%EF%BC%88OData%EF%BC%89%E3%82%A2%E3%82%AF%E3%82%BB%E3%82%B9%E3%81%A7%E3%81%8D%E3%82%8B%E3%82%88%E3%81%86%E3%81%AB%E6%A7%8B%E6%88%90%E3%81%97

CData API Server から Swagger Specの確認

それでは、まず構成したCData API Server から Swagger Spec を取得できるエンドポイントを確認したいと思います。

API Server の API ドキュメント画面に移動すると「/api.rsc/$swagger」というエンドポイントがあります。

このURLにをクリックすることで

f:id:sugimomoto:20190119212103p:plain

以下のような Swagger Spec を取得できます。Swagger Spec は CData API Server のリソースを作成した時点で自動的に生成されます。

f:id:sugimomoto:20190119212110p:plain

SwaggerHub

それでは、CData API Server の Swagger エンドポイントを使ってSwaggerHub でAPIを公開します。

SwaggerHub のプランは Free のもので大丈夫です。

SwaggerHub に移動して、左ナビゲーションから「Import and Document API」をクリック

f:id:sugimomoto:20190119212141p:plain

Path or URL にCData API Server のSwagger エンドポイント URLを入力します。

f:id:sugimomoto:20190119212148p:plain

おそらくログインが求められるので、CData API Server の API アクセス用ユーザーのIDとトークンを入力します。

f:id:sugimomoto:20190119212154p:plain

以下の画面から入手可能です。

f:id:sugimomoto:20190119212220p:plain

すると、以下のような画面に移るので、任意の名称とVersionを入力して「IMPORT OPENAPI」をクリック

f:id:sugimomoto:20190119212228p:plain

以下のようにもともとJSON だったSwagger エンドポイントのデータもYAML形式に整形されて、SwaggerHubで公開されます!

f:id:sugimomoto:20190119212234p:plain

もちろん、ここからClient SDKを Code Generate して使えるので、各種言語での実装が楽になりますね!

f:id:sugimomoto:20190119212242p:plain

Java クライント開発におけるWeb API の実装アプローチ:その1 Web API を活用する上で意識したい APIエコシステム

最近個人的に気になったトピックとして、世界のAPI Management 市場規模のニュースがありました。

Global API Management Market Worth USD 3,436.16 Million by 2022

f:id:sugimomoto:20190119181227p:plain サイトから引用

このニュースによると、世界のAPI Management 市場は2022年までに現在の2倍(3,000億円)の市場規模になると予想されていて、「これから2倍以上もAPIが出てくるかもしれないのかぁ」と想像がつかない部分と、ワクワクした部分が同居したような感覚になったのをよく覚えています。

もちろん、API Management 系ですので、一律すべてパブリックに公開されるわけではないでしょうが、今後今まで以上にAPI を使ったマッシュアップは重要性を増すことは間違いないように思います。

しかしながら、API Management もそうですが、同じように最近よく取り上げられる「API エコシステム」についても、以下の記事にあるように提供者側を中心としたトピックではないでしょうか。

f:id:sugimomoto:20190119181925p:plain サイトから引用 APIを利用したエコシステムの構築を阻む壁は何か? (1/4):CodeZine(コードジン)

でも、APIは最終的に使うユーザー・デベロッパーが居て、はじめて真価を発揮するものですが、使う側としてこういった API の流れ、API エコシステムに対していAPIを使うデベロッパー側はどのように関わるべきか? 意識するべきか? というお話はあまり多くありません。

そこで今回 API を使う側にとっての API エコシステムをテーマに、様々な API のスタイル・プロトコルJava のクライアント実装ベースで触りながら、それぞれの特性・エコシステムの特徴について、何回かに分けて連載をしていきたいと考えています。

今の所予定では、こんな感じです。

1. 一般的な REST API に対して HTTP Client ライブラリを利用する場合

2. Swagger(OpenAPI)Code Generateを利用する場合

3. OData ライブラリを利用する場合

4. GraphQL エンドポイントを利用する場合

5. CData JDBC Driver を利用する場合

6. まとめ

今回は初回ということで、そもそもなぜデベロッパーが API エコシステムを意識する必要があるのか?といった、このBlog記事をはじめるにあたって背景となった考えを述べていきたいなと思います。

なお、このBlogでは便宜上、API提供側をプロバイダー、API利用側をデベロッパーと書いています。

そもそもなぜデベロッパーが API エコシステムを意識する必要があるのか?

例えば、Microsoft のビジネスクラウドアプリケーション Dynamics 365(CRM)はC#VBSDKが公開されています。

なので認証周りや API 仕様を知らなくても、.NET 技術者は実装がしやすいのではないかなと思います。

では、JavaPythonデベロッパーは大人しくHTTP Client系ライブラリを使って実装するしか無いのか? というと、そういうわけではありません。(もちろんその実装アプローチを否定するわけではありません)

そこで一つ目を向けてほしいのが、Dynamics 365 の API は「OData」という仕様で公開されている、という点です。

以下は OData の公式サイトにあるエコシステムページです。

Ecosystem · OData - the Best Way to REST

f:id:sugimomoto:20190119181318p:plain

ここに掲載されているのは、OData を提供しているプロバイダーと、ODataを使いやすくするためのサービスやツール、ライブラリの一覧です。

探してみると、これらの中に JavaPython のクライアントライブラリも書かれているのがわかるかと思います。

これらライブラリを使うだけでも、純正ではないにせよ、実装のしやすさは格段に違うものになるのではないでしょうか。

他にも、例えば電子契約サービスの クラウドサイン ではOpenAPI (Swagger Hub)でドキュメントが公開されています。

https://app.swaggerhub.com/apis/CloudSign/cloudsign-web_api/0.8.0

f:id:sugimomoto:20190119181326p:plain

もちろん、これだけでも API 仕様書として見やすいことこの上ないのですが OpenAPI をベースとした Swagger Hub では Client SDK の自動生成もサポートしています。

これで Javaソースコードを生成すると、各 API Responseとなる JSON Object の デシリアライズ用 Class 生成からリクエストテストコードまで生成してくれます。

f:id:sugimomoto:20190119181335p:plain

このように、API のエコシステムを知っているだけで、開発スピードに雲泥の差が出てしまうのがイメージできるのではないかと思います。

また、単純に APIREST API と表現してしまう危うさがここにあります。

REST API は「仕様」では無いため、APIの構造を元にSDKを生成したり、共通のライブラリを元に様々な Web API にアクセスできるようには提供されていません。

プロトコルAPI ドキュメント系特有のエコシステムが発生しづらい原因がここにあります。

なので、これから取り上げる各仕様(Swagger・OData・GraphQL)に準拠しない場合、純正のSDKを使うか、自身でHTTPベースのやり取りを実装しなければいけません。

おわりに

初回はざっくりと、全体像のお話に終始しました。

次回から実際の実装コードも踏まえながら、見ていきたいと思います。

ちなみに、今回は「gRPC」「XML-RPC」「JSON-RPC」「SOAP」などのプロトコル郡には触れないです。RPC系は社内システム間での連携の側面が強いのと、SOAPも最近めっきり聞かないですしね。

SmartHR Web API を使って、Office365 にユーザー情報を自動的に登録:RSSBus Connect

前回の記事で SmartHR Web API の基本的な機能の確認をしました。

bit.ly

今回は実際にありそうなユースケースベースでお伝えしたいと思います。

シナリオ

SmartHRはおそらく会社の中で一番最初にユーザーを登録する場所なので、そのデータを元に会社の各システムにユーザー情報を連携させる、というニーズが強いんじゃないかなと思います。

そこで、私も個人的に利用しているOffice365 を使って、「新入社員が SmartHRに登録されたら、Office365に新しくユーザーを作成する」というシナリオでシステムを構成してみました。

f:id:sugimomoto:20190115182209p:plain

SmartHR と Office365 の接続にはRSSBus Connectというデータ連携ツールを利用します。

RSSBus Coonectとは?

RSSBus Connectは、ファイル、データベース、またはクラウドアプリケーションのデータをすべて1つのアプリケーションで簡単に統合することができるソフトウェアです。

アプリケーションとデータの接続を行い、Mrketoなどのマーケティングサービスから得た顧客情報をSalesforce等のSFAに連係したり、バイナリファイル転送・EDIによるプロセスの自動化も行うことが可能です。

image.png

RSSBus Connectは以下のようにフロー形式のUIで各データソースを繋ぐようにデータ連携のプロセスを開発することが可能です。

image.png

実行イメージ

処理内容は単純です。以下のような感じで、新しくSmartHRに新入社員が登録されたら

f:id:sugimomoto:20190115182317p:plain

RSSBusConnectがバッチで起動し、SmartHR Web APIを経由して、作成された社員情報を取得。

Office365 ユーザー情報に変換し、GraphAPIを経由してユーザー情報を作成します。

f:id:sugimomoto:20190115182329p:plain

以下のように登録されて完了となります!

f:id:sugimomoto:20190115182341p:plain

これで、新入社員が入るたびにユーザー情報を Office365 に作成する手間が省けるかなと。

RSSBus 利用手順

それでは実際の利用手順を見ていこうと思います。

今回はすでに私が作成したRSSbusのテンプレートがあるので、それをインポートして、認証情報などを設定するだけでサクッと試すことが可能です。

必要なもの

・RSSBus Connect

・Office365 Port

・Office365 アカウント(トライアルあり)

・SmartHR アカウント(トライアルあり)

Office365 ClientIDとClientSecretの取得について

RSSBusの準備を始める前に、Office365 アカウントについて1点注意事項があります。

RSSBus Connectには標準でOffice365 GraphAPIにアクセスするためのClientIDとClientSecretが提供されていますが、セキュリティ上の考慮のため、ユーザーの作成や削除権限が付与されていません。

下記手順でAzure ADに新しくOAuth用のアプリを作成し、対象のアプリにユーザー情報を作成するための権限を付与しておいてください。

kageura.hatenadiary.jp

RSSBus Connect と Office365 Portのインストール

RSSBus Connect は以下のURLからトライアルを取得可能です。

https://www.rssbus.com/

製品のダウンロード後、以下のようなウィザードに従ってインストールを進めます。

f:id:sugimomoto:20190116111423p:plain

そんなに難しい部分はありませんが、インストールやトライアルのアクティベーションは下記のBlogで詳しく解説しています。

qiita.com

Office365 Port のインストール

以下のURLからexeファイルをダウンロードして、インストールを実施します。

https://s3-ap-northeast-1.amazonaws.com/cdatajbuilds/sugimototest/SmartHR/CXTD-A_6950_free.exe

特に難しい設定はないので、そのまま次へ次へと進めればOKです。

f:id:sugimomoto:20190115184948p:plain

RSSBus Connect に SmartHR Script とテンプレートのインストール

現在、RSSBus Connect の標準機能としてSmartHRの接続は提供されていないません。

なので、私が作成しましたSmartHRの接続サンプルを以下のURLからダウンロードして、使ってみてください。

https://s3-ap-northeast-1.amazonaws.com/cdatajbuilds/sugimototest/SmartHR/SmartHR_Office365_UserConnectionTemplate.zip

テンプレートのインストール方法はこちらから。

qiita.com

SmartHR 接続情報の設定

それでは、実際に動かせるように RSSBus Connect の設定作業を進めていきます。

まず、SmartHR Web API を利用してJSONデータを取得している「GetSmartHRCrew」をクリックし、XMLの中の各設定値を変更します。

f:id:sugimomoto:20190115182229p:plain

変更が必要なものは「TenantId」と「AccessToken」です。この部分は前回のBlogでも解説しているので、参考にしてみてください。

必要に応じて、Domainも変更します。現在はサンドボックス環境に接続するために「daruma.space」を指定しています。

ちになみにデフォルトでは、夜の11時くらいに実行して、当日作成されたユーザーを取得する想定で、 SmartHRのWeb APIをリクエストしています。

設定完了後、「Save Changes」ボタンをクリックして、設定を反映させます。

Office365 認証設定

次に「InsertOffice365User」をクリックして、設定を行います。

前述したように、RSSBus Connect には標準でClientIDとClientSecretが提供されていますが、権限が不足しているので、独自に作成したアプリのClientIDとClientSecretを

「Advanced」→「Other」の項目の中に以下のようなフォーマットで入力します。「XXXXXX」の部分をそれぞれの値に差し替えてください。

OAuthClientId=XXXXXXXXXX;OAuthClientSecret=XXXXXX;

f:id:sugimomoto:20190115182235p:plain

次に「Settings」タブに移動して、接続するTenantID(hogehoge.onmicrosoft.com)を入力し、「Connect to Office365」をクリックすれば、OAuth認証が開始されます。

f:id:sugimomoto:20190115182243p:plain

OAuth認証のアクセス許可が承諾されれば、設定完了です。

マッピングの変更

最後に SmartHR のデータを Office365 ユーザーとして登録する際に、どの項目をどこに当てはめるのか? といったマッピングの構成を「XMLMapCrewToUser」で行います。

「XMLMapCrewToUser」をクリックすると、SourceとDestinationそれぞれのタブがあるので、ドラッグアンドドロップなどでマッピングを変更することができます。

f:id:sugimomoto:20190115182255p:plain

今回はユーザーを作成するにあたって必要最低限の以下の項目だけ設定しています。

・AccountEnabled = true を固定値で設定
・DisplayName = SmartHR の姓・名をつないで設定
・MailNickname = SmartHR の社員番号を設定
・UserPrincipalName = SmartHR のEmailを設定
・PasswordProfile_ForceChangePasswordNextSignIn = true を固定値で設定
・PasswordProfile_Password = P@ssw0rd!を固定値で設定

以上で設定は完了です。

手動実行の方法

手動で実行する場合は一番最初のモジュールである「GetSmartHRCrew」の「Output」タブから、「Receive」ボタンをクリックすればOKです。

f:id:sugimomoto:20190115182306p:plain

定期実行の構成

定期的に実行するように構成したい場合は、同じく「GetSmartHRCrew」の「Automation」タブから「Receive」を有効化して、任意の時刻設定を指定するだけです。

f:id:sugimomoto:20190115191417p:plain

おわりに

今回はOffice365 と接続しましたが、他にも RSSBus Connect はADやLDAPといったDirectoryサービスや各種クラウドサービスのコネクタを提供しているので、SmartHRのデータを様々なサービスへ手軽に展開できると思います。

[接続先コネクタ一覧]

f:id:sugimomoto:20190115193219p:plain

是非試してみてください。

クラウド労務管理ソフト SmartHR の Web API を使ってみる

f:id:sugimomoto:20190110152912p:plain

去年もいろいろなAPIを試してきたこのBlogですが、今年もはりきっていろんなAPIを試していきたいと思います。

新年一発目は、クラウド労務管理で最近かなり見かけるようになったなーと感じているSmartHRです!

公式サイトは以下からどうぞ。

smarthr.jp

Developer 向けの サイトも公開されています。

developer.smarthr.jp

続きを読む

「ZOZO 前澤社長のお年玉リツイート企画はどのくらい世の中に影響を与えたのか?」イベントを開催することになりました!

f:id:sugimomoto:20190117185929p:plain

先週公開した「ZOZO 前澤社長のお年玉リツイート企画はどのくらい世の中に影響を与えたのか?500万件超えのリツイート情報の取得と分析を個人的に試みる!(仮)」記事なんですが、思いの外様々な方々から反響をいただきました!

kageura.hatenadiary.jp

実際にPayPalでご支援いただける方も居て、大変ありがたい限りです!

そして、Facebookでたまたま知り合いました MaP design Founder の 渡部さんご協力のもと、1月28日に日本マイクロソフト品川本社セミナールームでイベントを開催することになりました!

ptix.at

当日は、様々な方のご協力のおかげで実現できた500万件の取得をベースに

Twitter APIを利用して500万件超えのリツイート情報を取得する方法」

「取得したデータから見る最新のTwitter マーケティング活用アプローチ」をお伝えする予定です!

あのリツイート騒動からなんとか1週間ほどで告知に漕ぎ着けられました。

ぜひぜひ、熱が冷めないうちにこのタイムリーなイベントに参加してみてください!


お金をもらえたはずなのに、むしろお金がかかるみたいなコンテンツに協力していただけた 渡部 さんと 日本マイクロソフトの Shohei Oda さんには大感謝です!

また、Blog公開時からご支援頂いた かがたさん、フロッグポッド小林さん、インフラジスティックス・ジャパン 東さん、エンバカデロ井之上さん、ありがとうございます!