見出し画像

kintone Java Client を使ってみました

サイボウズ株式会社 開発本部 People Experience チーム内 コネクト支援チームの貴島(@jnkykn) です。サイボウズは、U-22プログラムコンテスト 2023ダイヤモンドスポンサーです。U-22プログラミングコンテストへの参加に興味を持っていただくことを目的に、kintone を使ったワークショップをお申込みをいただいた各地の学校で開催しています。ワークショップでは、kintone の REST APIを使ったハンズオンに取り組んでいただくのですが、私は Javaでkintone REST APIにアクセスするための kintone Java Client を使ったことがなかったので自分でも試してみました。

kintoneのREST APIを使ってみよう

サイボウズの kintone は REST API を使って、データを扱うことができます。Node.js や Pythonからのアクセスは、GitHub Codespacesでサクッと試してみたのですが、Javaで試そうと思ったら少々苦戦したので、その顛末をレポートします。今回は、kintone 開発者ライセンスを利用して、cybozu.com の kintone 開発者環境に漫画データベースアプリを作成して、アクセスします。

kintone Java Client

kintone Java Client は、kintone REST API を Java プログラムから使う際に必要な処理をまとめたライブラリです。kintone Java Client に用意されたメソッドを呼び出すだけで kintone REST API を実行できるので、コードの記述量を減らすことができます。
kintone Java Client の導入説明には、Gradleプロジェクトの場合と、Maven プロジェクトの場合が紹介されています。私はどちらも使ったことがなかったのですが、ワークショップ講師のウィルさんに「Maven を使ったことがありますか?」と聞かれたので、Maven プロジェクトで試すことにしました。

Javaプログラムでkintone Java Client を利用してkintone 開発環境にREST APIでアクセスするイメージ
Javaプログラムで kintoneJava Client を利用して kintone 開発環境にアクセスする

こんにちは、Maven

Mavenは、Java のコンパイル環境です。公式サイトの説明に従って、Mavenをインストールしました。ドキュメントにあるとおり、バージョン確認をしようとしたら、JAVA_HOMEを環境変数に設定していなかったことがわかりました。

mvn -vを実行したところ、JAVA_HOME未定義エラーが表示された
環境変数のJAVA_HOMEが未設定のエラー

そもそもJDKをインストールしていなかったので、Java Downloads から、ぴかぴかの最新バージョン JDK 20をインストールしました。
これで無事に、Maven のバージョン確認もできたので、サンプルプロジェクトを参考に Maven プロジェクトを作ってみました。mvn install でビルドができると思ったのですが、エラーがたくさん…

mvn install を実行したところ、多くのエラーが発生してビルドできなかった
盛大にビルドエラーが出力されました

Eclipseと一緒に使ってみよう

Maven でプログラムを作るにあたって、解説ブログをいろいろ見てみたのですが、素の Maven プロジェクトを使っている例は Maven 公式ドキュメントくらいで、他は Eclipse にMaven 用の拡張を追加しているものばかりでした。Eclipse なら 前職の Java 開発案件で使っていたので、馴染みがあります。最初からこうすればよかった…。
今更ですが、Eclipse Version: 2023-06 (4.28.0)をインストールしました。
さらに、Eclipse に Maven 統合環境拡張を追加して、準備はOKです。

Eclipse Marketplace で maven integration をキーワードとして検索すると、Maven (Java EE)Integration for Eclipse WTP (Luna/Mars)1.2.0 が表示される
Eclipse用 Maven 統合をEclipse MarketPlaceからインストール

Eclipse の File メニューから、New >Maven Project を選択して、Maven 公式のサンプル「Hello, Maven Project」をもとにプロジェクトを作成、pom.xmlを設定しました。

File>New>Maven Project でMaven Projectが作成できる
File>New>Maven Project でMaven Projectが作成できる

App.java (標準出力にHello Maven World! と出力するだけのプログラム)

package main;

/**
 * Hello Maven World!
 */

public class HelloWorld {

	public static void main(String[] args) {
		System.out.println("Hello Maven World!");
	}
}

pom.xml

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>
  <groupId>maven.hello</groupId>
  <artifactId>hello-world</artifactId>
  <version>0.0.1-SNAPSHOT</version>
  
  <properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <maven.compiler.source>1.7</maven.compiler.source>
    <maven.compiler.target>1.7</maven.compiler.target>
  </properties>

  <!-- プラグインには Maven コンパイラを指定 -->
  <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>3.6.1</version>
            </plugin>
        </plugins>
    </build>
</project>

Eclipse の場合、確か、Runでビルドと実行ができたはず~と思ったのですが、Maven プロジェクトの場合は、Run As > Maven install を選択すると、mvn install が実行されます。

Mavenプロジェクトの実行は、Run As>Maven install を選択する
Run As Maven install でビルド開始

コマンドプロンプトを開いて、対象プロジェクトの target ディレクトリに出力されたjarファイルを実行すると、Hello Maven World! が出力されました。やったー!

コマンドプロンプトでjava -jar targetディレクトリに出力されたjarファイルのパスを指定して実行すると、Hello Maven World!と出力された
Hello Moven World!

Hello, kintone Java Client

さて、ここから、kintone Java Client を使ってみようと思ったのですが、10年以上ぶりの Java で、システム開発をしていたときの記憶は忘却の彼方。kintone Java Client をプロジェクトにパッケージとして取り込めば良いのかなと思いながら、GitHubのコードをダウンロードしてプロジェクトに import してしまったのです。
これが、躓きの始まりでした。

GitHubのkintone-java-client
kintone-java-client

pom.xml に kintone Java Client のための設定を追加したのに、ソースまで一緒に import するとは…

pom.xml にdependency を追加して、kintone Java Client の情報を追記

  <dependencies>
    <dependency>
      <groupId>com.kintone</groupId>
      <artifactId>kintone-java-client</artifactId>
      <version>1.4.0</version>
    </dependency>
  </dependencies>

App.java (kintoneのアプリの指定レコードを取得するプログラム)

package com.cybozu.devnet;

import java.util.List;

import com.kintone.client.KintoneClient;
import com.kintone.client.KintoneClientBuilder;
import com.kintone.client.RecordClient;
import com.kintone.client.api.record.AddRecordRequest;
import com.kintone.client.api.record.AddRecordResponseBody;
import com.kintone.client.api.record.GetRecordsByCursorResponseBody;
import com.kintone.client.model.record.CheckBoxFieldValue;
import com.kintone.client.model.record.Record;
import com.kintone.client.model.record.SingleLineTextFieldValue;

public class App {

	public static void main(String[] args) throws Exception {
	    String baseUrl = "https://■■■■■■■■■■■.cybozu.com/"; // ドメイン名
	    String apiToken = "■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■"; // API トークン
		long appId = 1L; // アクセス対象のアプリ ID
		long recordId = 1L; // 取得対象のレコード ID

		System.out.println("Hello, kintone Java Client");

		// API トークン認証を行う
		try (KintoneClient client = KintoneClientBuilder.create(baseUrl).authByApiToken(apiToken).build()) {
			// レコード操作用クライアントを取得
			RecordClient recordClient = client.record();
			// kintone からレコードを取得する
			Record record = recordClient.getRecord(appId, recordId);
			// レコードID を出力する
			System.out.println(record.getId());
		}

	}

}

ここから、ビルドが通らないという状態にハマってしまいました。

不足しているHttpClient関連のクラスが解決できないエラーが100以上出力されている
kintone Java Clientに必要なライブラリが不足しているので大量のエラーが
kintone Java Client に必要なライブラリの依存関係をpom.xmlに追加していた
無駄なことしてました…

関連するパッケージ情報をせっせと pom.xml に追加してエラーは減らせたのですが、ハタと、「import しちゃいけないものをimportしているのでは?」と気がついて、import していた kintone Java Client のソースコードをサクッと削除するとエラーがきれいになくなりました。そうなんです。pom.xml に依存関係が書いてあるので、わざわざソースコードを import しなくても良かったのです。これなら、ビルドできそうです。意気揚々と、Run As > Maven install を実行したのですが、ビルドエラーが発生しました。
pom.xml で指定した Java コンパイラのバージョンが古かったようです。

ソースオプション7は現在サポートされていません。8以上を指定してください。というBUILDエラーが出力された
Java のバージョン1.7はサポート外

pom.xml のJava コンパイラバージョンの指定を修正して 1.8 に

  <properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <maven.compiler.source>1.8</maven.compiler.source>
    <maven.compiler.target>1.8</maven.compiler.target>
  </properties>

これで、ビルドが成功しました!ばんざい!🎊

ビルド成功
ビルド成功しました!

コマンドプロンプトで実行すると、途中までは実行が成功したようでした。
例外メッセージを読むと、URI の '/' が重複しているようです。

Hello, kintone Java Client は出力されたが、レコード件数が表示されず、URIのエラーが表示された
実行途中で例外発生している

baseUrl には不要な '/' は無かったので、 末尾の '/' を除いてみました。

String baseUrl = "https://■■■■■■■■■■■.cybozu.com"; // ドメイン名

これで Run As > Maven clean、Run As > Maven install で再ビルドしました。

実行結果が正しく表示された
今度は、取得したレコード数まで表示できた

『漫画データベース』へのレコードの追加

これで気を良くした私は、練習用の開発環境に作った「漫画データベース」にレコードを追加して、追加した結果の情報を取得するように修正してみようと思いました。

修正したコード(mainのみ)

/**
 * kintoneの漫画データベースの1レコード目の取得後、1件追加して
 * 追加したレコードのタイトルを確認する
 **/
public class App {

	public static void main(String[] args) throws Exception {
	    String baseUrl = "https://■■■■■■■■■■■.cybozu.com"; // ドメイン名
	    String apiToken = "■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■"; // API トークン
		long appId = 1L; // アクセス対象のアプリ ID
		long recordId = 1L; // 取得対象のレコード ID

		System.out.println("Hello, kintone Java Client");

		// API トークン認証を行う
		try (KintoneClient client = KintoneClientBuilder.create(baseUrl).authByApiToken(apiToken).build()) {
			// レコード操作用クライアントを取得
			RecordClient recordClient = client.record();
			// kintone からレコードを取得する
			Record record = recordClient.getRecord(appId, recordId);
			// レコードID を出力する
			System.out.println("取得したレコードのID " + record.getId());

			// 追加用レコードオブジェクトを作成(本当はやりたくないけど、便宜上直接文字列を設定)
			Record addrecord = new Record();
			addrecord.putField("manga_title", new SingleLineTextFieldValue("ちいかわ"));
			addrecord.putField("manga_artist", new SingleLineTextFieldValue("ナガノ"));
			addrecord.putField("manga_genre", new CheckBoxFieldValue("ファンタジー"));

			// Add Record API 用リクエストを作成
			AddRecordRequest req = new AddRecordRequest();
			req.setApp(40L);
			req.setRecord(addrecord);
			// Add Record API 呼び出し(戻り値は、追加されたレコード番号)
			long addedId = client.record().addRecord(appId, addrecord);
			
			// 追加されたレコード番号 を出力する
			System.out.println("追加されたレコードのID=" + addedId);
			
			// 条件に一致するレコードの取得
			// カーソルの定義
			String cursorId = client.record().createCursor(appId, null, "レコード番号=" + addedId);
			while (true) {
				// カーソルを元にレコード一覧取得
				GetRecordsByCursorResponseBody resp = client.record().getRecordsByCursor(cursorId);
				List<Record> results = resp.getRecords();

				for( int i=0; i<results.size(); i++){
					System.out.println("追加されたレコードのタイトル=" + results.get(i).getSingleLineTextFieldValue("manga_title"));
				}
				// 次のデータが無ければループを終了
				if (!resp.hasNext()) {
					break;
				}
			}
		}

	}

}

実行してみたところ、うまくいきました。(実は、ここに至るまでに少々デバッグが必要だったのですが、割愛します)

新しくレコード追加して、追加されたレコードのIDとタイトルを出力できた
実行結果

kintone の漫画データベースにも、ちゃんとレコードが追加されていました。

kintoneの漫画データベースアプリにレコード番号=12、タイトル=ちいかわ、漫画家=ナガノが登録されている
追加されたレコードの確認

まとめ

久しぶりの Java プログラミングということもありましたが、初めての Maven プロジェクト環境構築に苦戦しました。最初はわけもわからず「なぜ、こんなエラーが!?」と考え込んでしまいましたが、Maven の仕組みを理解するにつれて、自分の環境設定の間違いが理解できるようになりました。Mavenプロジェクトは、pom.xml に依存関係を記述しておけば、必要なパッケージを管理しつつビルドしてくれるので、他のPCに移行する際など、パッケージのインストール漏れもなく安心だなと思いました。python やNode.js のサンプルプログラムと比べて、環境構築で手間取りましたが、こういうところもプログラミングの面白さだな~と再認識できました。kintone Java Client の readme を読むと、Gradleで開発されているそうなので、次は Gradle も試してみたいと思いました。

参考情報


この記事が気に入ったらサポートをしてみませんか?