[公式]Evernote API徹底活用レシピ

第4回データモデルとデータアクセスのサンプル(Java、Ruby)

前回は、Evernote APIのデータモデルやデータアクセスのについて解説しました。今回は具体的にJavaとRubyのサンプルコードを見ることで、その理解を深めたいと思います。

UserStoreサービスに接続するためのクライアント

まずはユーザ認証をするために、Thriftを通してUserStoreサービスに接続するためのクライアントを作成します。JavaとRubyのコードは以下の通りです。

UserStoreクライアントの作成(Java)
String userStoreUrl = "https://sandbox.evernote.com/edam/user";
THttpClient userStoreTrans = new THttpClient(userStoreUrl);
TBinaryProtocol userStoreProt = new TBinaryProtocol(userStoreTrans);
UserStore.Client userStore = new UserStore.Client(userStoreProt);
UserStoreクライアントの作成(Ruby)
userStoreUrl = "https://sandbox.evernote.com/edam/user"
userStoreTransport = Thrift::HTTPClientTransport.new(userStoreUrl)
userStoreProtocol = Thrift::BinaryProtocol.new(userStoreTransport)
userStore = Evernote::EDAM::UserStore::UserStore::Client.new(userStoreProtocol)

Evernote APIの実行環境には、サンドボックスサーバとプロダクションサーバがあります。Evernote APIを使う際には、まず一般ユーザーに影響を与えない安全な環境であるサンドボックスサーバ上で開発します。ソフトウェアの動作に問題がないことを十分に確認ができたら、プロダクションサーバに変更することで一般に公開します。UserStoreのサンドボックスサーバURLは https://sandbox.evernote.com/edam/user になります。このURLを引数として、Thrift用クライアントを作成します。

EvernoteはThriftのBinaryProtocolを使用していますので、HTTPクライアントを引数としてBinaryProtocolを作成します。最後にBinaryProtocolオブジェクトによって、UserStoreのクライアントを作成します。

UserStoreクライアントでのユーザ認証

次に、UserStoreクライアントを用いてユーザ認証をします。

ユーザ認証(Java)
AuthenticationResult authResult = null;
try {
  authResult = userStore.authenticate(username, password, consumerKey, consumerSecret);
} catch (EDAMUserException ex) {
  String parameter = ex.getParameter();
  EDAMErrorCode errorCode = ex.getErrorCode();
  if (errorCode == EDAMErrorCode.INVALID_AUTH) {
……
ユーザ認証(Ruby)
begin 
  authResult = userStore.authenticate(username, password, consumerKey, consumerSecret)
rescue Evernote::EDAM::Error::EDAMUserException => ex
  parameter = ex.parameter
  errorCode = ex.errorCode
  if (errorCode == Evernote::EDAM::Error::EDAMErrorCode::INVALID_AUTH)
……

userStore.authenticateでユーザ名とパスワードによる認証を行いますが、実際には引数としてconsumerKeyとconsumerSecretも渡します。これらはEvernote API Keyと呼ばれており、Evernote社に発行してもらわなければなりません。API Keyの取得方法については次回説明します。

ユーザ認証に失敗した場合は例外(EDAMUserException)が投げられますので、userStore.authenticateを使うときには例外を捕捉するようにします。捕捉した例外からエラーコードを取得できますので、ユーザ認証が失敗した原因を突き止める助けになるはずです。たとえば、ユーザ名、パスワード、API Keyのいずれかが問題だった場合は、エラーコードがINVALID_AUTHになります。

認証が成功した場合は、認証の結果から認証トークンを取得できます。認証トークンはユーザのデータにアクセスするときに必要になります。ここまでがUserStoreサービスの役割です。

認証トークン(Java)
String authToken = authResult.getAuthenticationToken();
認証トークン(Ruby)
authToken = authResult.authenticationToken

NoteStoreサービスによるユーザデータの操作

ユーザのデータを操作するためには、UserStoreサービスの代わりに、NoteStoreサービスを使います。NoteStoreのクライアントは、基本的にはUserStoreクライアントと同じ手順で作成できます。一点異なるのは、指定するURLです。UserStoreでは固定のURLを渡しましたが、NoteStoreでは認証結果から取得できるユーザ情報のshardIdを、ベースのURLに足したものを指定します。これによって、認証されたユーザのデータに紐付けられたNoteStoreクライアントになります。

NoteStoreの作成(Java)
String noteStoreUrlBase = "https://sandbox.evernote.com/edam/note/";
User user = authResult.getUser();
String noteStoreUrl = noteStoreUrlBase + user.getShardId();
THttpClient noteStoreTrans = new THttpClient(noteStoreUrl);
TBinaryProtocol noteStoreProt = new TBinaryProtocol(noteStoreTrans);
NoteStore.Client noteStore = new NoteStore.Client(noteStoreProt);
NoteStoreの作成(Ruby)
noteStoreUrlBase = "https://sandbox.evernote.com/edam/note/";
user = authResult.user
noteStoreUrl = noteStoreUrlBase + user.shardId
noteStoreTransport = Thrift::HTTPClientTransport.new(noteStoreUrl)
noteStoreProtocol = Thrift::BinaryProtocol.new(noteStoreTransport)
noteStore = Evernote::EDAM::NoteStore::NoteStore::Client.new(noteStoreProtocol)

例:ノートブック一覧の表示

NodeStoreクライアントを使ってユーザのデータにアクセスする例として、ユーザのノートブック一覧を表示するコードを挙げます。noteStore.listNoteBooksに認証トークンを渡すとノートブックのリストが返ってくるので、イテレーターを使ってノートブックの名前を表示します。

ノートブック一覧の表示(Java)
List notebooks = noteStore.listNotebooks(authToken);
for (Notebook notebook : notebooks) {
  System.out.println("Notebook: " + notebook.getName());
}
ノートブック一覧の表示(Ruby)
notebooks = noteStore.listNotebooks(authToken)
notebooks.each { |notebook| 
  puts "Notebook: #{notebook.name}"
}

例:ノートの作成

新しいノートを作成する方法は次のようになります。

まずNoteオブジェクトを作り、そこにタイトルとコンテンツをセットします。そして、NoteStore.createNoteにNoteオブジェクトを渡せば、Evernote上に実際に新規ノートが作成されます。各ノートには、GUIDというIDが付与されており、GUIDを使うことで直接ノートを指定することが可能です。作成されたノートはデフォルトのノートブックに保存されています。

Noteのコンテンツに設定するのはENML(Evernote Markup Language)です。ENMLはXMLですので、まず最初にxml宣言を書き、次に<!DOCTYPEの行でDTDの指定をします。ENMLのルートノードは<en-note>であり、その中に実際の内容が入ります。以下の例ではテキストを直接<en-note>に入れていますが、制限されたHTMLや、前回説明した<en-media>等、専用の要素も使えるようになっています。気をつけなければならないのは、EvernoteではENMLが正しく記述されているかどうかをサーバ側でチェックするようになっていることです。もし妥当でないXMLだった場合は例外が投げられるので、新しいノートは作成されません。

ノート作成(Java)
Note note = new Note();
note.setTitle("テストノート");
String content = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" + 
  "<!DOCTYPE en-note SYSTEM \"http://xml.evernote.com/pub/enml2.dtd\">" + 
  "<en-note>新しいノートを作りました</en-note>";
note.setContent(content);
Note createdNote = noteStore.createNote(authToken, note);
System.out.println("GUID: " + createdNote.getGuid());
ノート作成(Ruby)
note = Evernote::EDAM::Type::Note.new()
note.title = "テストノート"
note.content = '<?xml version="1.0" encoding="UTF-8"?>' +
  '<!DOCTYPE en-note SYSTEM "http://xml.evernote.com/pub/enml2.dtd">' +
  "<en-note>新しいノートを作りました</en-note>" 
createdNote = noteStore.createNote(authToken, note)
puts "GUID: #{createdNote.guid}"

これで一通り、ユーザ認証からデータ操作までのコードを説明しました。JavaとRubyのコードを同時に紹介しましたが、両者はとても似ています。違いは変数定義やクラスの指定方法など、言語自体の差異だけです。これはThriftを基盤にしていることの恩恵の一つです。APIを利用する際に、環境や開発者の好みに合わせて好きな言語を使えるというのは魅力だと思います。

次回以降の連載では主にAndroidでの開発を例に説明していく予定です。しかし、その内容は他の言語や環境でもほぼそのまま役に立つでしょう。また、Evernote APIのサンプルコードは、ウェブサービスAPIのEvernote APIアーカイブから取得することができます。JavaやRubyだけではなく他の言語のサンプルコードも含まれていますので、興味のある方は是非ご覧になってください。

次回は、今後説明するコードを実行して確かめられるようにするために、開発環境の設定や、API Keyなどの話をする予定です。

おすすめ記事

記事・ニュース一覧