25
第 36 第 Alfresco 第第第 Alfresco 5 第第第第第 REST API 第第第第第第第 2016/11/30 第第第第

Alfresco勉強会#36 alfresco 5でカスタムREST APIを作ってみよう

Embed Size (px)

Citation preview

Page 1: Alfresco勉強会#36 alfresco 5でカスタムREST APIを作ってみよう

第 36 回 Alfresco 勉強会Alfresco 5 でカスタム REST API を作ってみよう

2016/11/30おおたに

Page 2: Alfresco勉強会#36 alfresco 5でカスタムREST APIを作ってみよう

わたしは…おおたにです やってること

◦ 株式会社イージフで Alfresco や Liferay 周りの諸々◦ 2 児 (6 歳 , 2 歳 ) の父親業◦ Ingress ゆるふわエージェント業(現在休止気味…)◦ Pokemon Go ゆるふわトレーナー業(カビゴンが出ない…)

Page 3: Alfresco勉強会#36 alfresco 5でカスタムREST APIを作ってみよう

Agenda

Alfresco の Web Scripts というフレームワークと、それを利用したカスタム REST API の作成について簡単に紹介します Alfresco の REST API Spring Web Scripts 2 種類の Web Scripts Web Scripts を構成する 3 つの要素

◦ 定義ファイル◦ ロジック◦ テンプレート

カスタム REST API の作成 ルートオブジェクト Web Scripts の配置とリフレッシュ Java-backed Web Scripts

Page 4: Alfresco勉強会#36 alfresco 5でカスタムREST APIを作ってみよう

Alfresco の REST API

Alfresco は Platform と Share で構成される Platform は REST API でコア機能を提供する Share も画面を構成する一部コンポーネントが REST API で

HTML 断片を提供する Spring Web Scripts で実装される

Alfresco Platform(Alfresco のコア機能を REST API で

提供)

Alfresco Share

Alfresco Platform(Alfresco のコア機能を REST API で提

供)

Alfresco Share(Alfresco の GUI を提供 )

ブラウザ

HTTP Request HTTP Response

HTTP Request HTTP Response

Alfresco

Page 5: Alfresco勉強会#36 alfresco 5でカスタムREST APIを作ってみよう

Spring Web Scripts とは Alfresco の REST API を実装するフレームワーク Alfresco が開発を進め、 Spring Surf の一部として

SpringSource に寄贈。のはずが…

以後 Web Scripts と呼び、基本的な構成とREST API の実装方法を見ていきます

Page 6: Alfresco勉強会#36 alfresco 5でカスタムREST APIを作ってみよう

2 種類の Web Scripts

Repository Web Scripts(Data Web Scripts)

Presentation Web Scripts(Surf Web Scripts)

Alfresco Platform 生息場所 Alfresco PlatformAlfresco Share

主に XML や JSON レスポンス 主に HTML

Alfresco が管理するデータの取得や更新 目的 UI のカスタマイズや拡張

Alfresco のコアサービス呼び出しを伴う処理をカプセル化し、外部からのリクエストに

対してその処理結果を返す処理イメージ

Presentation Web Scripts が UIをレンダリングし、その中でRepository Web Scripts を呼んで必要なデータを取得し UI 上

に表示する

http://docs.alfresco.com/5.1/concepts/ws-types.html

Page 7: Alfresco勉強会#36 alfresco 5でカスタムREST APIを作ってみよう

Web Scripts を構成する 3 つの要素 定義ファイル

◦ 公開する REST API の情報を xml で定義する ロジック

◦ REST API 呼出時に実行するロジックを JavaScript もしくは Java で記述する◦ MVC で言うところの Controller◦ ビジネスロジックを実行し、レスポンス用のデータをセットする

テンプレート◦ REST API のレスポンスを生成するテンプレートを FreeMarker で記述する◦ MVC で言うところの View

※ 上記以外にも config ファイル等あるがここでは割愛

Page 8: Alfresco勉強会#36 alfresco 5でカスタムREST APIを作ってみよう

定義ファイルファイル名 : <web script id>.<http method>.desc.xml

REST API の定義を xml で記述する REST API の URL パターンやレスポンス形式、認証、トランザクション等を指定する

<webscript> <shortname>Category Search Sample</shortname> <description>Sample that finds all blog entries tagged with specified categories</description> <url>/sample/blog/category/{category}</url> <format default="html">argument</format> <authentication>guest</authentication> <transaction>required</transaction> <lifecycle>sample</lifecycle></webscript>

categorysearch.get.desc.xml

Page 9: Alfresco勉強会#36 alfresco 5でカスタムREST APIを作ってみよう

ロジックファイル名 : <web script id>.<http method>.js

REST API 呼出時に実行するロジックを JavaScript で記述する Alfresco の JavaScript API を使ってロジックを組み立てる

◦ ルートオブジェクトを介して、ユーザ / ノード等のコンテキスト情報やバックエンドの Java API (コアサービス等)を利用可能◦ ルートオブジェクト model, status あたりにレスポンスに必要な情報を格納すると、レスポンス用テンプレートで参照できる

※ ロジックは Java でも記述可能(後述)

var category = search.luceneSearch("PATH:\"/cm:generalclassifiable//cm:" + url.extension + "\"");if (category == undefined) { status.code = 404; status.message = "Category " + url.extension + " not found."; status.redirect = true;} else { // perform category search var nodes = search.luceneSearch("PATH:\"/cm:generalclassifiable//cm:" + url.extension + "//member\""); model.resultset = nodes;}

categorysearch.get.js

Page 10: Alfresco勉強会#36 alfresco 5でカスタムREST APIを作ってみよう

テンプレートファイル名 : <web script id>.<http method>.<format>.ftl

REST API のレスポンス内容を FreeMarker で記述する model, status 等の内容や、テンプレートで利用可能なルートオブジェクトを使ってレスポンスを構成する

<html> <body> <img src="${url.context}/images/logo/AlfrescoLogo32.png" alt="Alfresco" /> Category search: ${url.extension} <br> <table><#list resultset as node> <tr> <td><img src="${url.context}${node.icon16}"/> <td><a href="${url.serviceContext}/api/node/content/${node.nodeRef.storeRef.protocol}/${node.nodeRef.storeRef.identifier}/${node.nodeRef.id}/${node.name?url}">${node.name}</a> </tr></#list> </table> </body></html>

categorysearch.get.html.ftl

Page 11: Alfresco勉強会#36 alfresco 5でカスタムREST APIを作ってみよう

カスタム REST API を作ってみよう カスタム REST API の仕様は以下のとおり

◦ URL : /sample/search?q={ 検索文字列 }◦ 認証 : ユーザ認証◦ ロジック : 指定した検索文字列での検索結果を返す◦ レスポンス形式 : html◦ レスポンス内容 : 検索でヒットしたノードの名前とパスを表示する

Page 12: Alfresco勉強会#36 alfresco 5でカスタムREST APIを作ってみよう

カスタム REST API を作ってみよう定義ファイル 主要な設定項目

◦ url : リクエストパラメータを含む API の呼出 URL◦ format : レスポンスフォーマット◦ authentication : API 呼び出しに必要な認証

<webscript> <shortname>Search Sample</shortname> <description>Search Sample</description> <url>/sample/search?q={searchTerm}</url> <format default="html" /> <authentication>user</authentication> <transaction>required</transaction> <lifecycle>sample</lifecycle></webscript>

samplesearch.get.desc.xml

Page 13: Alfresco勉強会#36 alfresco 5でカスタムREST APIを作ってみよう

カスタム REST API を作ってみようロジック よく使われるルートオブジェクト

◦ args : リクエストパラメータにアクセスするためのオブジェクト◦ model : レスポンスに含めるデータを格納するオブジェクト◦ search : 検索関連 Java API をラップして提供するオブジェクト

if (args.q == undefined || args.q.length == 0) { model.results = [];} else { model.results = search.luceneSearch("TEXT:" + args.q);}

samplesearch.get.js

Page 14: Alfresco勉強会#36 alfresco 5でカスタムREST APIを作ってみよう

カスタム REST API を作ってみようテンプレート #if, #list 等の FreeMarker ディレクティブを利用 model がロジックから共有され、 results と書くだけで

model.results にアクセス可能 JavaScript API 上でのノードオブジェクト(以下の node 等)は ScriptNode 型で、便利なプロパティを多数提供する

<html> <head><title>Search Sample Web Script</title></head><body><#if results?has_content> <table> <tr><th></th><th>name</th><th>path</th></tr><#list results as node> <tr> <td><img src="${url.context}${node.icon16}"/></td> <td>${node.name}</td> <td>${node.displayPath}</td> </tr></#list> </table><#else><p>No search results</p></#if></body></html>

samplesearch.get.html.ftl

http://docs.alfresco.com/5.1/references/API-JS-ScriptNode.html

Page 15: Alfresco勉強会#36 alfresco 5でカスタムREST APIを作ってみよう

ルートオブジェクト Alfresco の JavaScript API で利用可能なオブジェクト

◦ 実体は BaseProcessorExtension を継承した Java オブジェクト◦ カスタムルートオブジェクトを実装することも可能

いくつかの種類のオブジェクトがある◦ Web Scripts の基本機能を提供 : model, args, session, url …◦ コンテキストノードを提供 : companyHome, document, person, space …◦ Java API を提供 : actions, jsonUtils, people, search, workflow …◦ コアサービスをそのまま提供 : siteService, taggingService …

記述場所によって利用できるものが異なるPlatform 側のロジック : http://docs.alfresco.com/5.1/references/API-JS-rootscoped.htmlPlatform 側のテンプレート : http://docs.alfresco.com/5.1/references/API-FreeMarker-defaultmodel.htmlShare 側のロジック : http://docs.alfresco.com/5.1/references/APISurf-rootscoped.htmlShare 側のテンプレート : http://docs.alfresco.com/5.1/references/APISurf-templates.html / http://docs.alfresco.com/5.1/references/APISurf-components.htmlhttp://docs.alfresco.com/5.1/references/dev-extension-points-javascript-root-objects.html

Page 16: Alfresco勉強会#36 alfresco 5でカスタムREST APIを作ってみよう

Web Scripts ファイルの配置場所 Repository Web Scripts

◦ Alfresco 上の /Company Home/Data Dictionary/webscripts/◦ <tomcat_dir>/shared/classes/alfresco/extension/templates/webscripts/◦ classpath:alfresco/templates/webscripts/

Presentation Web Scripts◦ <tomcat_dir>/shared/classes/alfresco/web-extension/site-webscripts/◦ classpath:alfresco/site-webscripts/

Page 17: Alfresco勉強会#36 alfresco 5でカスタムREST APIを作ってみよう

Web Scripts のリフレッシュ Web Scripts の内容修正を反映させる方法は以下の 2 つ1. Alfresco を再起動する

◦ 反映に時間がかかる◦ JAR ファイルでパッケージされた Web Scripts の変更も対応可能

2. Web Scripts 管理画面でリフレッシュする◦ 一瞬で反映可能◦ JAR ファイルでパッケージされた Web Scripts の変更は反映不能

※ 以下のページの Refresh Web Scriptsボタンをクリックするだけ Platform : http://localhost:8080/alfresco/service/index Share : http://localhost:8080/share/page/index

Page 18: Alfresco勉強会#36 alfresco 5でカスタムREST APIを作ってみよう

カスタム REST API を動作確認する Web Scripts 管理画面にてカスタム REST API が正常に登録されているか確認( Browse by Web Script URI などで)

◦ Platform : http://localhost:8080/alfresco/service/index◦ Share : http://localhost:8080/share/page/index

実際に HTTP リクエストを投げて結果を確認

Page 19: Alfresco勉強会#36 alfresco 5でカスタムREST APIを作ってみよう

Java-backed Web Scripts

Java でロジックを記述した Web Scripts 定義ファイルとテンプレートは JavaScript の場合と一緒

<webscript> <shortname>Java-backed Web Scripts Search Sample</shortname> <description>Java-backed Web Scripts Search Sample</description> <url>/sample/javasearch?q={searchTerm}</url> <format default="html" /> <authentication>user</authentication> <transaction>required</transaction> <lifecycle>sample</lifecycle></webscript>

samplejavasearch.get.desc.xml

<html> <head><title>Search Sample Java-backed Web Scripts</title></head><body><div><p>Java-backed Web Scripts Sample</p></div><#if results?has_content> <table> <tr><th>name</th><th>path</th></tr><#list results as node> <tr><td>${node.name}</td><td>${node.path}</td></tr></#list> </table><#else><p>No search results</p></#if></body></html>

samplejavasearch.get.html.ftl

Page 20: Alfresco勉強会#36 alfresco 5でカスタムREST APIを作ってみよう

Java-backed Web Scriptsロジックの記述 ロジックを Java クラスで記述する

◦ DeclarativeWebScript クラスを継承◦ executeImpl() にロジックを記述

package jp.aegif.alfresco.sample;

public class SampleSearchWebScript extends DeclarativeWebScript { private SearchService searchService; private NodeService nodeService; private PermissionService permissionService;... protected Map<String, Object> executeImpl(WebScriptRequest req, Status status, Cache cache) { Map<String, Object> model = new HashMap<String, Object>(); String searchTerm = req.getParameter("q"); if (searchTerm != null && !searchTerm.isEmpty()) { ResultSet resultSet = searchService.query(StoreRef.STORE_REF_WORKSPACE_SPACESSTORE, SearchService.LANGUAGE_FTS_ALFRESCO, searchTerm); List<Map<String, String>> results = new ArrayList<Map<String, String>>(); for (ResultSetRow resultSetRow : resultSet) { NodeRef nodeRef = resultSetRow.getNodeRef(); String name = (String)nodeService.getProperty(nodeRef, ContentModel.PROP_NAME); String path = (String)nodeService.getPath(nodeRef).toDisplayPath(nodeService, permissionService); Map<String, String> result = new HashMap<String, String>(); result.put("name", name); result.put("path", path); results.add(result); } model.put("results", results); } return model; }}

SampleSearchWebScript.java

Page 21: Alfresco勉強会#36 alfresco 5でカスタムREST APIを作ってみよう

Java-backed Web ScriptsWeb Scripts 定義とロジックの紐付け Spring bean 定義でロジッククラスを紐付ける

◦ bean id : webscript.<web script id>.<http method>◦ class : ロジック実装クラス( DeclarativeWebScript クラスを継承)◦ parent : webscript bean を指定

<?xml version='1.0' encoding='UTF-8'?><!DOCTYPE beans PUBLIC '-//SPRING//DTD BEAN//EN' 'http://www.springframework.org/dtd/spring-beans.dtd'>

<beans> <bean id="webscript.samplejavasearch.get" class="jp.aegif.alfresco.sample.SampleSearchWebScript" parent="webscript"> <property name="searchService" ref="SearchService" /> <property name="nodeService" ref="NodeService" /> <property name="permissionService" ref="PermissionService" /> </bean></beans>

webscript-context.xml

Page 22: Alfresco勉強会#36 alfresco 5でカスタムREST APIを作ってみよう

Java-backed Web Scripts

以下のコマンドで実行mvn integration-test -Prun

Page 23: Alfresco勉強会#36 alfresco 5でカスタムREST APIを作ってみよう

まとめWeb Scripts を使ったカスタム REST API の作成方法を紹介しました 今回使用したソースコード

https://bitbucket.org/tasuku_otani/alfresco-java-backed-web-scripts-sample

ビルド環境の作り方http://www.slideshare.net/terajun/alfresco26-alfresco-sdkhttp://labo-blog.aegif.jp/2016/05/alfresco-sdk-22jar.html

Page 24: Alfresco勉強会#36 alfresco 5でカスタムREST APIを作ってみよう

リファレンス Alfresco で実際に使われている Web Scripts

◦ Platform : https://github.com/Alfresco/community-edition/tree/master/projects/remote-api

◦ Share : https://github.com/Alfresco/share/tree/master/share

Web Scripts に関する Alfresco のドキュメント◦ Platform :

http://docs.alfresco.com/5.1/references/dev-extension-points-webscripts.html

◦ Share : http://docs.alfresco.com/5.1/concepts/dev-extensions-share-surf-web-scripts.html

Jeff Potts’ Web Scripts tutorial ( must read だそうです…)http://ecmarchitect.com/alfresco-developer-series-tutorials/webscripts/tutorial/tutorial.html

Page 25: Alfresco勉強会#36 alfresco 5でカスタムREST APIを作ってみよう

おまけ aegif Labo blog やってます

http://aegif-labo.blogspot.jp/

現時点での Alfresco CE の最新版は…◦ 最新版は 5.2 の 201611-EA ( Early Access )https://community.alfresco.com/docs/DOC-6301https://community.alfresco.com/docs/DOC-6467◦ GA ( Generally Available )リリースの最新版は 5.1 の 201605-GAhttps://community.alfresco.com/docs/DOC-6297https://sourceforge.net/projects/alfresco/