本文件旨在說明 FourJs Genero 4GL 3.21 及後續更高版本中,High-Level Web frame的開發方式,並與傳統方法進行比較,著重於其優勢和簡化之處。Genero3.21為鼎新/鼎捷 T100 ERP V3.1以上採用的Genero版本,用戶可透過 fglrun -V 檢視版本訊息。
1. High-Level Web Frame 與傳統寫法之比較
在 Genero 4GL 中,傳統的 Web Service 開發方式通常涉及較多的底層操作,例如手動處理 SOAP 訊息、WSDL 解析等。而 High-Level Web Frame的引入,旨在簡化這些流程,讓開發者能夠更專注於業務邏輯的實現。
1.1 傳統寫法
* 需要使用 `com.WebService` 和 `com.WebOperation` 等 COM 物件來定義 Web Service 和其操作。
* 需要較多地關注 WSDL 文件的細節。
* 錯誤處理和資料轉換需要較多手動編碼。
* 對於 RESTful 風格的 Web Service,支援相對較弱。
1.2 High-Level Web Framework
* **簡化:** 透過固定寫法的 server,呼叫『註冊』在主4gl內的 function,使用 `FUNCTION ATTRIBUTES` 設定REST參數、環境,即直接生成可運作的 service。
* **直觀:** 開發者可以使用熟悉的 4GL 語法,無需深入了解底層的 SOAP 或 WSDL。
* **RESTful 支援:** 提供對 RESTful 風格 Web Service 的良好支援,包括 HTTP 方法、URI 模板等。
* **效率:** 減少了開發所需的時間和程式碼量。
1.3 優勢總結
| 特性 | 傳統寫法 | High-Level Web Service |
| :------- | :--------------------------------------- | :------------------------------------------ |
| 開發難度 | 較高,需要理解底層細節 | 較低,直面需求段 4GL 開發 |
| 程式碼量 | 較多 | 少 |
| 可讀性 | 較差,程式碼較為冗長 | 好,程式碼更簡潔易懂 |
| 維護性 | 較差,修改和除錯較為困難 | 好,程式碼結構清晰,易於維護 |
| REST 支援 | 較弱 | 良好 |
2. as.xcf 的設定方法
`as.xcf` 檔案是 Genero Application Server (GAS) 的主要設定檔。 High-Level Web Framework 仍歸屬於 Service部分,且建議將主要 as.xcf中額外配置子路徑,以便『減少維護的過程中必須因重啟服務造成停機』,可極大地減少用戶於更新時無法使用的困擾。
2.1 主要 as.xcf 中配置 service 路徑
在 `as-topprd.xcf` 檔案為例,在 <APPLICATION_SERVER> 的 <SERVICE_LIST>段落內,可調整配置如下:
```xml
<APPLICATION_SERVER>
...
<SERVICE_LIST>
<GROUP Id="top">$(res.zone.config)/xcf/high</GROUP>
</SERVICE_LIST>
</APPLICATION_SERVER>
```
* `res.zone.config`: `T100` 系統下 erp/cfg 配置路徑。
上述增加後,須完成 fastcgidispatch 的重啟 (或在系統可重啟的時間,重啟 web service),後續即可在 $ERP/cfg/xcf/high 目錄下維護 個別的 xcf 檔案,隨條即用,不須再做重新啟動 fastcgidispatch。
2.2 設定個別服務自己使用的 as.xcf
經過 2.1 設定後,即可前往 $TOP/erp/xcf/high 配置個別端口應用程式。例如:
```xml
<?xml version="1.0" encoding="UTF-8" ?>
<APPLICATION Parent="ws.default"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="https://4js.com/ns/gas/5.00/cfextws.xsd">
<EXECUTION>
<!-- ENVIRONMENT FOR Genero/DB -->
<ENVIRONMENT_VARIABLE Id="LD_LIBRARY_PATH">/usr/lib64:/usr/lib/oracle/21/client64/lib:/usr/lib64::/usr/lib/jvm/java-17-openjdk-17.0.13.0.11-4.el9.x86_64/lib/server</ENVIRONMENT_VARIABLE>
<ENVIRONMENT_VARIABLE Id="ORACLE_HOME">/usr/lib/oracle/21/client64</ENVIRONMENT_VARIABLE>
<ENVIRONMENT_VARIABLE Id="ORACLE_SID">topprd</ENVIRONMENT_VARIABLE>
<ENVIRONMENT_VARIABLE Id="TWO_TASK">topprd</ENVIRONMENT_VARIABLE>
<ENVIRONMENT_VARIABLE Id="TNS_ADMIN">/u2/oracle/topprd</ENVIRONMENT_VARIABLE>
<ENVIRONMENT_VARIABLE Id="NLS_LANG">AMERICAN_AMERICA.AL32UTF8</ENVIRONMENT_VARIABLE>
<ENVIRONMENT_VARIABLE Id="FGLPROFILE">/u1/etc/fglprofile.topprd</ENVIRONMENT_VARIABLE>
<PATH>$(res.zone.erp)/asa/42m</PATH>
<MODULE>asa_asap000.42m</MODULE>
</EXECUTION>
</APPLICATION>
```
* 若需要連結數據庫,則須將數據庫客戶端需求的環境變數加入此處,如ORACLE會需要 `ORACLE_HOME`、`ORACLE_SID`、`TNS_ADMIN`、`FGLPROFILE` 等。
* 子程式的部分,請以 IMPORT的方式撰寫,盡量避免使用 link連結的方法。
3. 撰寫服務的 4GL Function 與 ATTRIBUTES
使用 High-Level Web Framework 時,關鍵在於使用 `FUNCTION ATTRIBUTES` 子句來定義 4GL 函式的 Web Service 相關屬性。
3.1 FUNCTION ATTRIBUTES 設定
以下透過簡單的案例介紹 FUNCTION 後方的屬性 (ATTRIBUTES) 設定方法。
```4gl
PUBLIC FUNCTION Add( a INTEGER ATTRIBUTES(WSQuery),
b INTEGER ATTRIBUTES(WSQuery) )
ATTRIBUTES (WSGET, WSPath='/add',
WSDescription='Simple query sample')
RETURNS (INTEGER)
RETURN a+b
END FUNCTION
```其中,在變數部分的 ATTRIBUTES 為
* **WSQuery**:標示此參數為傳入參數
在 FUNCTION層級的 ATTRIBUTES 為
* **WSGET**: 採用 GET 方法
* **WSPath**: URL路徑。整個路徑為:http://IP/ws/r/主as.xcf中配置的路徑/子xcf檔名/此處設定的路徑
* **WSDescription**: Service說明
3.2 主程式設定
主程式的部分,可以直接複製 $FGLDIR/demo/WebServices/books/server/BookService.4gl 的main段落來使用,或整隻參考
其中,註冊 WEB Service的部分為下列段落:
```4gl
# Register all public function with a REST Verb of module Users.4gl as a rest service
CALL Com.WebServiceEngine.RegisterRestService("BookService", "Books")
```
注意,縱使如範例程式,其 Web Service也是在同一隻 4GL內,此 4GL 一樣要做註冊 (如本隻作業呼叫 RegisterRestService ,第一個參數是 4gl 名稱,第二參數是服務名稱。
更詳細的屬性說明,請參考 FourJs Genero 的官方文件。
https://4js.com/online_documentation/fjs-fgl-manual-html/#fgl-topics/t_gws_restful_high_level_quick_start_service_module.html
FUNCTION內的屬性文件
https://4js.com/online_documentation/fjs-fgl-3.21.05-manual-html/#fgl-topics/r_gws_high_level_rest_api_attributes.html
4. 測試
測試時,可以用 http://IP/ws/r/主as.xcf中配置的路徑/子xcf檔名?OpenAPI.json 的方式查看輸出輸入所許要使用的參數,來查看程式是否可以正常運作。