リモートAPIの自動生成 (RemoteApiGen)

Lasta RemoteApiライブラリを想定した自動生成ツールです。

RemoteApiGenとは?

リモートAPIクラスの自動生成

リモートAPIのクラス、BehaviorやParam/Returnクラスを手動で作るのは大変です。 リモートサーバーのAPIスキーマ定義があるなら自動生成してしまいましょう。それが RemoteApiGen です。

RemoteApiGenはFreeGenモジュール

RemoteApiGenは、DBFluteのFreeGenを利用してクラスを自動生成します。

DBFluteクライアントのfreegen配下にRemoteApiGenのモジュールを配置し、freeGenMap.dfpropにFreeGen定義をして、 (RemoteApiGenに必要なアプリのファイルを用意した上で)自動生成を行っていきます。

RemoteApiGenのアーキテクチャ

RemoteApiGenの全体像

ざっくりこのようになっています。

LastaFlute RemoteApiGen Architecture

リモートサーバーのswagger.jsonをもらう

リモートサーバーから swagger.json をもらうことが前提です。外部APIなどで swagger.json がもらえない場合は、インターフェース仕様書などから swagger.json を作成すれば自動生成できます。どうしても swagger.json を用意できない場合は RemoteApiGen は利用できません。

自動生成を調整するrule.jsを定義する

...rule.js という自動生成の振る舞いを調整するための設定ファイルを定義します。 JavaScriptで表現された設定ファイルとなっています。RemoteApiGenがFreeGen実行の中でJavaScriptを評価します。

アプリのrule.jsとフレームワークのrule.jsがあり、アプリのrule.jsでJavaScript関数のオーバーライドを行ってデフォルトの振る舞いを変更します。

アプリのrule.js
関数をオーバーライドして自動生成の振る舞いをアプリに合わせていく
フレームワークのrule.js
デフォルトの挙動、このコードを読んでアプリのrule.jsの参考に

アプリのrule.jsは手動で作成します。(一番最初はExampleのrule.jsを参考にしましょう)

Behaviorはジェネレーションギャップ

それぞれのBehaviorは、DBFluteと同じようにBs/Exクラスがジェネレーションギャップで自動生成されますので、Exクラス側で手動修正で調整することができます。

また、すべてのBehaviorが継承するスーパークラスも自動生成され、これも手動修正をすることができます。yourDefaultRule()などそのリモートサーバーで共通の設定を実装しましょう。

Abstract...Bhv
自動生成(上書きされない)、yourDefaultRule() などの設定を
Bs...Bhv
自動生成(上書きされる)、requestメソッドなどが定義される
...Bhv
自動生成(上書きされない)、必要に応じてruleOfメソッドなどをオーバーライド

RemoteApiGenのファイル構成

ざっくりこのようになっています。☆マークの付いてるファイルが重要ファイルです。

e.g. RemoteApiGen file structure @Directory
[PROJECT_ROOT]
 |-src/main/java
 |  |-[application-package]
 |  |  |-app
 |  |  |-bizfw
 |  |  |-dbflute
 |  |  |-mylasta
 |  |  |-remote
 |  |  |  |-[remote-server-package]
 |  |  |  |  |-[business-packages]
 |  |  |  |  |  |-Bs[Business]Bhv.java // 自動生成されたBehaviorのBsクラス、人が修正しない
 |  |  |  |  |  |-[Business]Bhv.java // 自動生成されたBehaviorのExクラス、必要に応じて人が修正
 |  |  |  |  |
 |  |  |  |  | // 自動生成されたスーパークラス、すべてのBehaviorが継承している
 |  |  |  |  | // yourDefaultRule()などの実装をする、人が修正しまくる
 |  |  |  |  |-AbstractRemote[RemoteServer]Bhv.java
 |
 |-src/main/resources
 |  |-...
 |  |-remoteapi
 |  |  |-di
 |  |  |  | // 自動生成されたDi xml, remote_api.xmlからincludeされる、人が修正しない
 |  |  |  |-remoteapi_[remote-server].xml
 |  |  |
 |  |  |-schema
 |  |  |  |
 |  |  |  | // アプリのrule.js, 自動生成の振る舞いを定義、人が修正しまくる ☆☆☆
 |  |  |  | // フレームワークのRemoteApiRule.jsの関数をオーバーライドしてアプリに合うように調整する
 |  |  |  |-remoteapi_schema_[remote-server]_rule.js
 |  |  |  |
 |  |  |  | // リモートサーバーからもらったswagger.json, 基本的に人が修正しない(もらうだけ) ☆☆
 |  |  |  |-remoteapi_schema_[remote-server]_swagger.json
 |  |-...
 |  |-app.xml // アプリの基点となるDi xml, remote_api.xml を include, 人が修正する
 |  |-remote_api.xml // 自動生成されたDi xmlをincludeするDi xml, 人が作成する
 |
 |-dbflute_[xxxdb]
 |  |-dfprop
 |  |  |-...
 |  |  |-freeGenMap.dfprop // FreeGen定義、リモートサーバーごとに設定を追加、人が修正する ☆
 |  |
 |  |-freegen // FreeGenモジュールのディレクトリ、アップグレード以外では人は修正しない
 |  |  |-remoteapi
 |  |  |  |-container // 自動生成されるDi xmlのVelocityテンプレートのディレクトリ
 |  |  |  |-doc       // 自動生成されるドキュメントのVelocityテンプレートのディレクトリ
 |  |  |  |
 |  |  |  |-ControlFreeGenRemoteApiJava.js // RemoteApiGenの自動生成処理の根幹ロジック ☆
 |  |  |  |-ControlFreeGenRemoteApiJava.vm // FreeGenの制御ファイル
 |  |  |  |-README.md        // 読んでください
 |  |  |  |-...vm            // 自動生成されるBehaviorやBeanなどのVelocityテンプレート
 |  |  |  |-RemoteApiRule.js // フレームワークのrule.js, アプリ側はこれをオーバーライドする ☆☆
 |

RemoteApiGenのセットアップ

RemoteApiGenのダウンロード

本家リポジトリのreleasesからzipファイルがダウンロードできます。

本家のreleases
dbflute-example-with-remoteapi-gen - releases

RemoteApiGenの使い方

  1. ダウンロードしたzipを解凍して [DBFluteクライアント]/freegen/remoteapi に配置
  2. freeGenMap.dfprop に RemoteApiGen の FreeGenリクエストを定義
  3. 同じくschemaディレクトリに、リモートサーバーのswagger.jsonを配置
  4. src/main/resources/remoteapi/schema にrule.jsを作成 (Exampleを参考に)
  5. manageタスクで freegen (12) を実行 成功すると remoteパッケージにクラスが自動生成される
  6. 自動生成された Abstract...Bhv.java にて yourDefaultRule() を適切に実装

ファイル構成ドキュメントを参考に。

RemoteApiGenのアップグレード

古いRemoteApiGenを削除して、新しいRemoteApiGenを配置します。

releasesからダウンロードしたzipを解凍して [DBFluteクライアント]/freegen/remoteapiディレクトリ完全入れ替え すればアップグレード完了です。

※freegen/remoteapiディレクトリ配下はアプリで独自に修正していないことが前提です。

freeGenMap.dfpropの書き方

freeGenMap.dfprop での RemoteApiGen向けのFreeGen定義は、このように書きます。

e.g. how to define freeGen definition, to maihama-showbase application @dfporp
; RemoteApiMaihamaShowbase = map:{
    ; resourceMap = map:{
        ; baseDir = ../src/main
        ; resourceType = SWAGGER
        ; resourceFile = $$baseDir$$/resources/remoteapi/schema/remoteapi_schema_maihama-showbase_swagger.json
    }
    ; outputMap = map:{
        ; outputDirectory = $$baseDir$$/java
        ; package = org.docksidestage.remote
    }
    ; optionMap = map:{
        ; ruleJsPath = ../src/main/resources/remoteapi/schema/remoteapi_schema_maihama-showbase_rule.js
    }
}

ひとつのリモートサーバーに対して、一つのFreeGen定義をします。

FreeGenリクエスト名
RemoteApi[相手のリモートサーバーの名前]が慣習
resourceType
必ず SWAGGER を指定 (swagger.jsonを読み込むため)
resourceFile
リモートサーバーの swagger.json のファイルを相対パスで指定
package
自動生成するクラスのベースとなるパッケージを指定
ruleJsPath
rule.jsファイルを相対パスで指定

ここで定義さえすれば自由にディレクトリやファイル名、パッケージなどを変更できますが、アプリケーションの都合が無い限りは慣習通りに定義することをオススメします。 (ドキュメントやExampleと合っていたほうがわかりやすいと思いますので)

rule.jsの書き方

rule.jsは、JavaScript (ECMAScript 5.1ベース: Nashorn、Sai上での実行のため) で記述されているので、定義の仕方に少々特徴があります。

関数のオーバーライドの仕方

フレームワークの RemoteApiRule.js の関数をオーバーライドする場合はこのようになります。

e.g. how to override in rule.js @JavaScript
// _/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/
// フレームワークのRemoteApiRule.jsでの定義
// (objectの定義になっている)
// _/_/_/_/_/_/_/_/_/_/

    target: function(api) {
        ...
    },

 ↓↓↓

// _/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/
// アプリのrule.jsでのオーバーライド定義
// (関数を代入しているので "=" になっている)
// (@Overrideコメントは慣習)
// _/_/_/_/_/_/_/_/_/_/

// @Override
remoteApiRule.target = function(api) {
    ...
    
    // フレームワーク側の処理を呼び出すなら、baseRuleで参照できる
    // (Javaのsuperみたいな感じ)
    //return baseRule.target(api);

    ...
} // ここのカンマは不要、こっちはオブジェクト定義ではないので

アプリ独自のオブジェクトの定義

アプリのrule.jsで独自に定義したオブジェクトを利用する場合はこのようになります。

e.g. how to override in rule.js @JavaScript
// name and type mapping for e.g. classification
var manualMappingClassMap = {
    'memberStatus': 'org.docksidestage.dbflute.allcommon.CDef.MemberStatus',
    'selectedReason': 'org.docksidestage.dbflute.allcommon.CDef.WithdrawalReason'
};

// @Override
remoteApiRule.pathVariableManualMappingClass = function(api, pathVariable) {
    return manualMappingClassMap[pathVariable.name];
}

// @Override
remoteApiRule.beanPropertyManualMappingClass = function(api, beanClassName, property) {
    return manualMappingClassMap[property.name];
}

rule.jsを綺麗に整理整頓

重要なファイルなので綺麗に保ちましょう。タグコメント入れたり、定義順序をRemoteApiRule.jsに合わせることをオススメします。

また、何のためのオーバーライドか?何を変更しているのか?のコメントもしっかり書くと良いでしょう。

e.g. how to override in rule.js @JavaScript
// _/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/
// RemoteApiGen your rule settings as ECMAScript5 (related to RemoteApiRule.js in freegen)
// _/_/_/_/_/_/_/_/_/_/

// ======================================================================================
//                                                                                  Const
//                                                                                  =====
...Constタグコメントの関数のオーバーライドをここに



// ======================================================================================
//                                                                                  Base
//                                                                                 ======
// @Override
remoteApiRule.target = function(api) { // you can select generated API 
...

...Baseタグコメントの関数のオーバーライドをここに



// ======================================================================================
//                                                                               Behavior
//                                                                               ========
// generate hierarchical behaviors if resources hanving many nests
// @Override
remoteApiRule.behaviorSubPackage = function(api) {
...

...Behaviorタグコメントの関数のオーバーライドをここに



// =======================================================================================
//                                                                            Param/Return
//                                                                            ============
// extends common super class for e.g. HTTP headers
// @Override
remoteApiRule.returnExtendsClass = function(api, properties) {
...

...Param/Returnタグコメントの関数のオーバーライドをここに



// =======================================================================================
//                                                                                  Option
//                                                                                  ======
// @Override
remoteApiRule.typeMap = function() {
...

...Optionタグコメントの関数のオーバーライドをここに

RemoteApiRule.jsの細かい挙動

フレームワークのrule.jsである RemoteApiRule.js の関数の細かい挙動に関して調べたい場合は、RemoteApiRule.js自体のソースコードを読むのに加えて、それを制御している ControlFreeGenRemoteApiJava.js を読むと良いです。

rule.jsのお決まりパターン

自動生成するAPIを絞り込む

デフォルトでは、すべてのpathが自動生成対象になります。

絞り込むためには、target()関数をオーバーライドします。(Baseタグコメント配下)

e.g. how to override target() in rule.js @JavaScript
...Baseタグコメント配下に定義すると良いでしょう

// @Override
remoteApiRule.target = function(api) { // you can select generated API 
    if (api.url.indexOf('/method/onbodyjson') !== -1 && api.httpMethod === 'get') { // get$onbodyjson()
        return false; // unsupported at RemoteApiGen for now (you can request by your manual method)
    }
    return true;
}

api.urlでpathが取得できるので、対象や除外をうまく調整しましょう。

階層ごとにBehaviorを自動生成する

デフォルトでは、1階層分のBehaviorしか自動生成されず、リモートサーバーがRESTful APIなどで階層が深い場合は、それぞれ巨大なBehaviorになってしまいます。

階層ごとにBehaviorを自動生成するには、behaviorSubPackage()関数をオーバーライドします。

e.g. how to override behaviorSubPackage() in rule.js @JavaScript
...Behaviorタグコメント配下に定義すると良いでしょう

// generate hierarchical behaviors if resources hanving many nests
// @Override
remoteApiRule.behaviorSubPackage = function(api) {
    return this.subPackage(api).replace(/^([^.]*)\.(.+)/, '$1.$2'); // default is $1 only
}

$1に対して、.$2を追加しただけです。少しオーバーライドの範囲が広いので、アップグレードしたときはフレームワーク内の修正を追従しましょう。

requestメソッドにHTTPメソッドを必ず付ける

デフォルトでは、同じpathに対して複数のHTTP Methodが存在する場合にだけHTTP Methodがrequestメソッドに付与されます。 (protectedのruleOfメソッドも同様です)

リモートサーバーがRESTful APIなどHTTP Methodが存分に使っている場合は、運用途中の再自動生成でメソッド名が変わってしまう可能性もあります。

requestメソッドにHTTP Methodを必ず付けるには、behaviorRequestMethodName()関数をオーバーライドします。 同時に、ruleOfメソッドもHTTP Methodを必ず付けるようにしておいたほうが良いので、behaviorRuleMethodName()関数もオーバーライドします。

e.g. how to override behaviorSubPackage() in rule.js @JavaScript
...Behaviorタグコメント配下に定義すると良いでしょう

// always HTTP Method on request method
// @Override
remoteApiRule.behaviorRequestMethodName = function(api) {
    var methodPart = manager.camelize(this.subPackage(api).replace(this.behaviorSubPackage(api), '').replace(/\./g, '_'));
    return 'request' + manager.initCap(methodPart) + manager.initCap(api.httpMethod);
}

// always HTTP Method on rule method
// @Override
remoteApiRule.behaviorRuleMethodName = function(api) {
    var methodPart = manager.camelize(this.subPackage(api).replace(this.behaviorSubPackage(api), '').replace(/\./g, '_'));
    return 'ruleOf' + manager.initCap(methodPart) + manager.initCap(api.httpMethod);
}

multipleHttpMethodかどうかの判定をやめて固定でHTTP Methodが入るようにしています。少しオーバーライドの範囲が広いので、アップグレードしたときはフレームワーク内の修正を追従しましょう。

Param/Returnクラスのsuffixを変更する

デフォルトでは、Param/Returnというsuffixのクラスが生成されますが、例えばBody/Resultに変更したい場合は、以下のように設定します。

e.g. how to override returnExtendsClass() in rule.js @JavaScript
...Param/Returnタグコメント配下に定義すると良いでしょう

// change suffix 'Param' to 'Body' for Parameter class
// @Override
remoteApiRule.paramClassName = function(api, detail) {
    return baseRule.paramClassName(api).replace(/Param$/g, 'Body');
}

// change suffix 'Return' to 'Result' for Return class
// @Override
remoteApiRule.returnClassName = function(api, detail) {
    return baseRule.returnClassName(api).replace(/Return$/g, 'Result');
}

Returnクラスにスーパークラスを定義する

デフォルトでは、Returnクラスには特に何もスーパークラスは付与されません。

Returnクラスにスーパークラスを定義するには、returnExtendsClass()関数をオーバーライドします。

e.g. how to override returnExtendsClass() in rule.js @JavaScript
...Param/Returnタグコメント配下に定義すると良いでしょう

// extends common super class for e.g. HTTP headers
// @Override
remoteApiRule.returnExtendsClass = function(api, properties) {
    if (api.httpMethod === 'get' && !api.url.endsWith('}/')) { // means List GET
        return "org.docksidestage.bizfw.remoteapi.AbstractListGetReturn";
    } else {
        return baseRule.returnExtendsClass(api, properties);
    }
}
  • ここでは、RESTful API の List GET のときだけスーパークラスを定義している

スーパークラスは、bizfwパッケージ配下のどこかの業務的なパッケージに置くと良いでしょう。

固定的にレスポンスのHTTP Headerなどの値をReturnに持たせたいときなどに使うと良いです。 rule.handleHeaderResponse()とコラボレーションさせましょう。

Returnクラスにインターフェースを定義する

デフォルトでは、Returnクラスには特に何もインターフェースは付与されません。

Returnクラスにインターフェースを定義するには、paramImplementsClasses()関数をオーバーライドします。 (Param/Returnタグコメント配下)

スーパークラスの returnExtendsClass()関数と同じような感じで定義できます。

フィールド名のキャメル変換ルールを変える

デフォルトでは、パスパラメーターやJSON上の項目名を小文字スネークケースであることを前提にして、Javaクラスのフィールドではキャメルケースで自動生成します。

フィールド名のキャメル変換ルールを変えるには、fieldNamingMapping()関数をオーバーライドします。

e.g. how to override typeMap() in rule.js @JavaScript
...Optionタグコメント配下に定義すると良いでしょう

remoteApiRule.fieldNamingMapping = function() {
    return {
        'path': this.FIELD_NAMING.CAMEL_TO_LOWER_SNAKE,
        'query': this.FIELD_NAMING.CAMEL_TO_LOWER_SNAKE,
        'formData': this.FIELD_NAMING.CAMEL_TO_LOWER_SNAKE,
        'json': null,
        'xml': this.FIELD_NAMING.CAMEL_TO_LOWER_SNAKE
    };
}
  • ここでは、JSONだけ変換をしないようにしている

path, query, jsonなどそれぞれに設定が分かれていて、変換を止めたい場合は null にします。

JSONをパースするのはLastaFluteのJsonManager(Gson)になりますので、そちらの変換ルールと合っていないといけません。 ([App]JsonResourceProviderにて設定できます)

java.util.Listを別のリストにする

デフォルトでは、リスト項目は java.util.List で生成されます。

java.util.Listを別のリストにするには、typeMap()関数をオーバーライドします。

e.g. how to override typeMap() in rule.js @JavaScript
...Optionタグコメント配下に定義すると良いでしょう

// @Override
remoteApiRule.typeMap = function() {
    var typeMap = baseRule.typeMap();
    typeMap['array'] = 'org.eclipse.collections.api.list.ImmutableList';
    return typeMap;
}
  • ここでは、Eclipse Collections の ImmutableList を利用している

JSONをパースするのはLastaFluteのJsonManager(Gson)になりますので、例えば Eclipse Collections の ImmutableList で受け取るのであれば、LastaFlute側の設定で ImmutableList を解釈できるようにしておきましょう。 ([App]JsonResourceProviderにて設定できます)

区分値項目をCDef型で定義する

デフォルトでは、区分値項目もStringなどで生成されます。 swagger.jsonの情報だけでは「どのCDefクラスに紐付くのか?」わからないためです。

区分値項目をCDef型で定義するには、pathVariableManualMappingClass()関数とbeanPropertyManualMappingClass()関数をオーバーライドします。

e.g. how to override ...ManualMappingClass() in rule.js @JavaScript
...Optionタグコメント配下に定義すると良いでしょう

// name and type mapping for e.g. classification
var manualMappingClassMap = {
    'memberStatus': 'org.docksidestage.dbflute.allcommon.CDef.MemberStatus',
    'selectedReason': 'org.docksidestage.dbflute.allcommon.CDef.WithdrawalReason'
};

// @Override
remoteApiRule.pathVariableManualMappingClass = function(api, pathVariable) {
    return manualMappingClassMap[pathVariable.name];
}

// @Override
remoteApiRule.beanPropertyManualMappingClass = function(api, beanClassName, property) {
    return manualMappingClassMap[property.name];
}
  • パッケージ名の指定が冗長だと思ったら、ここは自由なJavaScriptなのでお好きなように最適化を

関連付けるのはアプリ区分値のCDefでもOKです。(というかその方が良いでしょう)

パスパラメーターとBeanプロパティで関数が分かれていますので、それぞれの ...ManualMappingClass をオーバーライドして、CDefとの関連付けを行います。 そのために、独自のオブジェクトを宣言して、そこで関連付けを定義しています。

項目名に対しての関連付けなので、項目名が曖昧なものだと関連付けるのが難しくなります。 (オーバーライドした関数の中で他の要素を使ってピンポイントで判定することはできるかもしれませんが複雑になるかもしれません)

ここは開発者がつどつど追加修正していく箇所になるかと思いますので、しっかりわかるようにコメントなどを付けたり綺麗に保つようにしましょう。

その他いろいろなrule.js設定

Exampleの remoteapi_schema_example_rule.js を参考に。

様々なパターンの設定が書かれているので、こちらをコピーしてカスタマイズして利用すると良いでしょう。

対応できてないこと

こちらの欄、まだ推敲中です。

OpenAPI v3.x (2.0に変換が必要)

OpenAPI(Swagger) v2.0に変換して利用してください。

ただし、OpenAPI v3.XにはOpenAPI(Swagger) v2.0に存在しない機能 (複数のサーバー、oneOf/anyOf、メディアタイプごとの異なるスキーマなど) があるため、変換後の定義は厳密には等価ではないです。

memo: 変換方法を書く。 たしかlasta-metaのdiffの機能を作ったときにv2とv3の比較もできた気がするので、javaで変換できるしれない。 外部ツールでの変換とjavaでの変換で整理。(有償ツール、Saasは避けたい)

その後、ユーザーの方から npm の api-spec-converter を使ったら変換できてRemoteApiGenの自動生成もできたとのフィードバックがあった。thanks! (v3固有の機能をあまり使ってないswagger定義だったのかもしれないが...) (2023/06/20)

allOf (限定自動生成)

allOfは、現状(2022/06/27時点)では、1件目の設定されているschemaのみが自動生成対象になります。 また、$refのみサポートで、フラットは未対応です。

つまり、以下の例だと "$ref": "#/definitions/ErrorModel" のみが対象になります。

e.g. allOf pattern @swagger.json
"ExtendedErrorModel": {
    "allOf": [
        {
            "$ref": "#/definitions/ErrorModel"
        },
        {
            "$ref": "#/definitions/ErrorModelSecond"
        },
    ]
}

...

"ExtendedErrorModel": {
    "allOf": [
        {
            "type": "object",
            "required": [
                "rootCause"
            ],
            "properties": {
                "rootCause": {
                    "type": "string"
                }
            }
        }
    ]
}

パス全体に対するproperty (パラメーターやHTTPヘッダー)

自動生成対象外です。

パス全体に対するpropertyがある場合、HTTPメソッド(GET,POSTなど)相当で判断されるため、rule.jsで除外する必要があります。

Httpヘッダー

RemoteApiGenとしては自動生成対象外ですが、RemoteApiRuleでリクエスト/レスポンスのHTTPヘッダーのハンドリングはできるので、手動作成のBehaviorであれば扱えます。

ファイルアップロード (手動作成が必要)

RemoteApiGenとしては自動生成対象されるはず (要検証) ですが、リクエストを送信するためにはBehavior側で工夫が必要です。

Exampleが lastaflute-test-fortress にありますので参考に。

レスポンスのschemaが複数 (限定自動生成)

レスポンスのschemaが複数あっても1件目 (HTTPステータスコード200?) のみが自動生成されます。

わからないことはぜひ聞いて

RemoteApiGenはコミッターも少なく、細かいところまでドキュメントを整備するリソースもないのが正直なところです。

わからないことや相談したいことがあれば、ぜひMLやSlackなどでお聞きください。

コミッター向け

内部的な挙動は、だいたいこんな感じです。@since 0.9.1

e.g. internal flow since 0.9.1 @model
 +-------------------+
 | ControlFreeGen.vm | read by DBFlute FreeGen
 +-------------------+
    |
    |   +--------------------------------+
    +-> | ControlFreeGenRemoteApiJava.vm | sets $scriptEngine 
        +--------------------------------+ puts 'generator', 'manager'
               |
               v
   +------------------------------------------+
   | ControlFreeGenRemoteApiJava.js@process() | uses DfFreeGenRequest
   +------------------------------------------+
       |-request loop
       |-eval RemoteApiRule.js       )
       |-eval RemoteApiLogic.js      )--------------------+-------------------------+
       |-eval [app]_rule.js          )                    |                         |
       |-processHull() --+                                v                         |
       |-clean()         |                              +------------------+        |
                         v                              | RemoteApiRule.js |        |
   +----------------------------------------------+     |                  |        |
   | ControlFreeGenRemoteApiJava.js@processHull() |     |  merged with     |   o    |
   +----------------------------------------------+  +->|  [app]_rule.js <--- /|\   |
       |-processBean()                               |  +------------------+  / \   |
       |   |-RemoteApiBean.vm                     )  |                       (you)  |
       |                                          )  |                              |
       |-processBhv()                             )  |    +-------------------+     |
       |   |-RemoteApiAbstractBehavior.vm         )--+--> | RemoteApiLogic.js | <---+
       |   |-RemoteApiBsBehavior.vm               )       +-------------------+
       |   |-RemoteApiExBehavior.vm               )           indent()
       |   |-RemoteApiExBehaviorTest.vm           )           deriveCategolizedImportClassList()
       |   |-RemoteApiDiXml.vm (Lasta Di)         )           deriveBehaviorMethodList()
       |                                          )           deriveBeanImportList()
       |-processDoc()                             )           deriveBeanProperty()
       |   |-RemoteApiDocHtml.vm                  )
       |   |-(write it to LastaDoc)

Exampleプロジェクト

本家リポジトリ

本家リポジトリがそのままExampleになります。

LastaFluteのテストプロジェクト

lastaflute-test-fortressプロジェクト (テスト用のプロジェクト) に、RemoteHarborBhv という RemoteApi の Example コードもあります。

RemoteHarborBhv
手動作成、単一プロジェクト (harbor)
RemoteMaihamaHangarBhv
手動作成、マルチプロジェクト (maihama - hangar)
RemoteMaihamaShowbaseBhv
自動生成, マルチプロジェクト (maihama - showbase)
RemoteSwaggerPetstoreBhv
自動生成, petstoreを使った動作確認用
RemoteSwaggerTrickyBhv
自動生成, トリッキーな動作確認用

Great Thanks

RemoteApiGenは、"LUXA" より、コントリビュート頂きました。

ありがとうございます!