2022年8月の「テクてくLotus技術者夜会」に参加予定なのですが、アジェンダにある「Project KEEP (REST API)」について予習しておこうと思い、この記事「Domino Rest API (KEEP) のチュートリアル」のとおり進めたところ、ハマりどころがいくつかありましたので、ここで共有したいと思います。
これからチュートリアルを進める方の参考になれば幸いです。
このエントリを書いている時点では、Domino REST API は最新ベータ版は 2022年7月版 EAP(Early Access Program)として Docker イメージで提供されています。私はこれを使用しました。
ハマりどころ(1):パーミッション
Docker イメージを使うには、それを動かすホストマシンが必要です。私は自前のPC(Windows 10) に Docker Desktop を導入しているので最初はそちらで進めていました。
ところがチュートリアルの「Domino REST APIの管理画面での操作」でホストマシンにダウンロードした Demo.nsf のパーミッションを変えてコンテナへコピーするところで、ホストマシンが Windows のためにパーミッション変更する方法が分からず一旦中断となりました。結局のところ、WSL2(Windows Subsystem for Linux) に Ubuntu をインストールし、そこに Docker をインストールして Docker イメージを使用することで Demo.nsf のパーミッション変更ができ、先に進むことができました。
実は Docker Desktop 上でパーミッション変更せずに先に進めたところ、問題が発生してしまいました。みなさんはパーミッションを変更できるホストマシンから操作するようにしてほしいと思います。
ハマりどころ(2):誤り
まだベータ版ということであるあるかとも思いますが、チュートリアルに記載のとおりにコマンドを叩いてもエラーになることがあります。
今回はチュートリアルの「curl もしくは postman でREST APIの操作」に誤り(バージョンがあがって仕様が変わったかも?)があり、ハマりました。
「文書を作成する」
チュートリアルには次のように GET と書かれていますが POST が正しいです。
GET /api/v1/document?dataSource=<スコープ名>
「文書を取得する」
チュートリアルには
/api/v1/document/<文書の UNID>/default?dataSource=<スコープ名>
と書かれていますが、これでは「404 This is not the URL you seek」となります。これを/api/v1/document/<文書の UNID>?dataSource=<スコープ名>
のように "/default" を除去することで文書を取得することができました。
「文書を削除する」
こちらも「文書を取得する」と同じく "/default" を除去することで文書を削除することができました。
ハマりどころ(3):削除権限の反映
チュートリアルでは、「文書を削除する」で文書を削除できる設定に変えるため、Demo.nsf に作成されるリソースファイル「REST/<スキーマ名>.json」を編集するよう指示されています。私はこのとおり編集してみたものの「403 You are not allowed to delete the document at this mode」のエラーが出続けました。私の環境では Docker コンテナを再起動したところ反映されました。コンテナあるいは Domino を再起動するのではないにしろ、変更した設定を反映するのに何かアクションしなければならないのかもしれません。
ハマりどころ(4):リソースファイルにビューが反映されないことがある
チュートリアルの「Domino REST APIの管理画面での操作」に従って操作し、手順16で[Activated Views]にビューが追加されているにもかかわらずリソースファイル「REST/<スキーマ名>.json」に追加した内容が反映されておらず、REST APIでビュー一覧を取得できない、ということがありました。管理画面からビューの追加や削除をしながらリソースファイルの内容を確認する、といったことをしていると反映されることがあり、そのタイミングで REST API を実行すればビュー一覧を取得することができました。変更した設定内容がキチンと反映してほしいな、と思いました。
以上です。
なお、今回の問題解決に大いに役に立ったのは下の情報です。こちらのほうが仕様変更があった場合に速やかに反映されるかもしれません。
https://opensource.hcltechsw.com/domino-keep-docs/
今回のチュートリアルにある文書の操作などを行うため、先に取得した認証トークンを使用します。認証トークンの文字列は長いので覚えることができないし、いちいち控えておくのも面倒ということもあって、下の様な LotusScript でエージェントを作ってテストを進めていました。以下のコードは試行錯誤した履歴を含むので見づらいと思いますが、現時点で(私の環境では)きちんと動作しました。※サーバー停止は動きません
%REM Agent DominoRESTAPI Created 2022/08/16 by administrator Description: Domino Rest API サンプル環境を利用した学習 本エージェント実行前にやる事 1. Docker Windows の起動、restapiコンテナの起動 restapiコンテナ以外のコンテナが起動する場合、終了しておく 2. ipconfig でWSLのIPアドレス確認、HOSTS修正 REQ_TARGET_HOST のホストのIPアドレスがHOSTSと異なる場合、修正する %END REM Option Public Option Declare Sub Initialize Dim ss As New NotesSession Dim req As NotesHTTPRequest Dim nav As NotesJSONNavigator Dim elm As NotesJSONElement Dim arr As NotesJSONArray Dim obj As NotesJSONObject Dim url$, data$, token$, unid$ Dim headers Const USER_NAME = "Administrator" Const USER_PASSWORD = "password" Const REQ_PROTOCOL = "http://" Const REQ_TARGET_HOST = "himawari.noteslab.local:8880" Const ADMIN_HOST = "himawari.noteslab.local:8889" Const REQ_API = "/api/v1" Set req = ss.Createhttprequest() req.Preferjsonnavigator = True '認証トークンの取得 url = REQ_PROTOCOL & REQ_TARGET_HOST & REQ_API &_ "/auth" req.Setheaderfield "Content-Type", "application/json" data = |{"password":"| & USER_PASSWORD & |","username":"| & USER_NAME & |"}| Set nav = req.Post( url, data ) If InStr( req.Responsecode, "200" ) = 0 Then Exit Sub Set elm = nav.Getelementbyname( "bearer" ) If elm Is Nothing Then Exit sub token = elm.Value Print "[DEBUG PRINT] token = " & token 'DB一覧の取得 url = REQ_PROTOCOL & REQ_TARGET_HOST & REQ_API &_ "/admin/access" Call req.Resetheaders() req.Setheaderfield "Content-Type", "application/json" req.Setheaderfield "Authorization", "Bearer " & token data = |{"checkAllNsf": true,"onlyConfigured": false}| Set nav = req.Post( url, data ) If InStr( req.Responsecode, "200" ) = 0 Then Exit Sub Set arr = nav.Getelementbyname( "databases" ).Value Set elm = arr.Getfirstelement() While Not elm Is Nothing Set obj = elm.Value If obj.Getelementbyname( "path" ).Value = "Demo.nsf" Then Set obj = obj.Getelementbyname( "activeConfigurations" ).Value Print "[DEBUG PRINT] activeConfigurations.demodbscope = " & obj.Getelementbyname( "demodbscope" ).Value End If Set obj = Nothing Set elm = arr.Getnextelement() Wend 'データベース内のビューを確認する url = REQ_PROTOCOL & REQ_TARGET_HOST & REQ_API &_ "/lists?type=views&dataSource=demodbscope" Call req.Resetheaders() req.Setheaderfield "Content-Type", "application/json" req.Setheaderfield "Authorization", "Bearer " & token Set nav = req.Get( url ) If InStr( req.Responsecode, "200" ) = 0 Then Exit Sub Print nav.Stringify() '文書を作成する url = REQ_PROTOCOL & REQ_TARGET_HOST & REQ_API &_ "/document?dataSource=demodbscope" Call req.Resetheaders() req.Setheaderfield "Content-Type", "application/json" req.Setheaderfield "Authorization", "Bearer " & token data = |{"first_name": "George","last_name": "Branthwaite","email": "gbranthwaite0@nba.com","gender": "Male","ip_address": "91.254.204.27","Form": "Customer"}| Set nav = req.Post( url, data ) If InStr( req.Responsecode, "200" ) = 0 Then Exit Sub Print nav.Stringify() Set elm = nav.Getelementbyname( "@unid" ) unid = elm.Value '文書を取得する url = REQ_PROTOCOL & REQ_TARGET_HOST & REQ_API &_ "/document/" & unid & "?dataSource=demodbscope" Call req.Resetheaders() req.Setheaderfield "Content-Type", "application/json" req.Setheaderfield "Authorization", "Bearer " & token Set nav = req.Get( url ) If InStr( req.Responsecode, "200" ) = 0 Then Print "文書の取得に失敗しました。 responseCode = " & req.Responsecode Print nav.Getelementbyname( "message" ).Value 'Exit Sub End If Print nav.Stringify() '文書を削除する url = REQ_PROTOCOL & REQ_TARGET_HOST & REQ_API &_ "/document/" & unid & "?dataSource=demodbscope" '※メモ 'Demo.nsf をDesignerで開き、リソースにあるファイル「REST/demodbschema.json」の '「/forms/formModes/deleteAccessFormula/formula」の値を @trueにしたが削除できず、 'それでも"not allowed to delete"になるので、Dockerコンテナを再起動したところ、削除できた。 Call req.Resetheaders() req.Setheaderfield "Content-Type", "application/json" req.Setheaderfield "Authorization", "Bearer " & token Set nav = req.Deleteresource( url ) If InStr( req.Responsecode, "200" ) = 0 Then Print "文書の削除に失敗しました。 responseCode = " & req.Responsecode Print nav.Getelementbyname( "message" ).Value 'Exit sub End If Print nav.Stringify() 'ログアウトする url = REQ_PROTOCOL & REQ_TARGET_HOST & REQ_API &_ "/auth/logout" Call req.Resetheaders() req.Setheaderfield "Content-Type", "application/json" req.Setheaderfield "Authorization", "Bearer " & token data = |{"logout": "Yes"}| Set nav = req.Post( url, data ) If InStr( req.Responsecode, "200" ) = 0 Then Print "ログアウトに失敗しました。 " & req.Responsecode Print nav.Stringify() 'Exit Sub End If Print nav.Stringify() 'サーバーを停止する url = REQ_PROTOCOL & ADMIN_HOST &_ "/shutdown" 'bearerトークンを残す意味で直上のログアウトをせずに実行してみたものの動作せず、 '結果は「401 Unauthorized, boiling TAR」となった。 Call req.Resetheaders() req.Setheaderfield "Content-Type", "application/json" req.Setheaderfield "Authorization", "Bearer " & token data = |{"shutdownkey" : "The End is near!!","StopServer" : true}| Set nav = req.Post( url, data ) If InStr( req.Responsecode, "200" ) = 0 Then Print "サーバー停止に失敗しました。 " & req.Responsecode 'Exit Sub End If Print nav.Stringify() End Sub
0 件のコメント:
コメントを投稿