# iComposer Quick Start

## 1. Background
iComposer is a low-code backend platform with two core functional modules:
> - **RESTful API**: The externally exposed interface, equivalent to the Controller in Spring MVC.
> - **Service Function**: The business logic behind the API, equivalent to Service/Manager in traditional backend development.

In this Quick Start Guide, the Hello World example aims to demonstrate how to create a Service Function with basic greeting logic and a RESTful API (POST/GET) that invokes this Service Function, helping new users quickly grasp the core usage of iComposer.

## 2. Overall Menu Navigation
Before we start, please make sure that you have all read and write authority to make the operations beforehand. 

For the first time to operate, we recommend that the user follow the steps below to navigate all the menus:

1. Log in to the home page of InsureMO and locate iComposer menu in the left menu bar.

2. Check Restful API menu.

3. Check Service Function Menu.

![menu](./image/iComposer_quick_start_image/menu.png)

## 3. Service Function  

This chapter explains to new users: Service Function represents the "business logic" layer and will be invoked by RESTful APIs. We create a Hello World Service Function to illustrate.

### 3.1. Create a Service Function
1. In the left menu of iComposer, locate **Service Function**.

![sf-overview-search](./image/iComposer_quick_start_image/sf-overview-search.png)

2. Users are advised to search the search bar for service functions that have been entered into the system. If no relevant service function is found, a new one should be created.
3. Click `Add`.

![sf_blank](./image/iComposer_quick_start_image/sf_blank.png)

4. Fill in the basic information (example):
   - Name: `HelloWorldService`
   - Description: `Demo: The function receives a name parameter (from Map type request data), first logs a greeting message containing the name to the system log, and subsequently returns the concatenated greeting string encapsulated in a Map. Assigns "World" as default if the name parameter is empty or not present.`
   - Module: `policy admin`
   - Group: `test_api`

![sf_info](./image/iComposer_quick_start_image/sf_info.png)

5. Click `Save` to upload the information. `Exit` will discard all your edits.

### 3.2. Define Input and Output Structures
We define the input and output data structures for the Service Function as follows:
- **Input (Input DTO)**:
  - `requestData`: Map (contains the "name" field of String type; "name" is optional, with "World" as the default value)
- **Output (Output DTO)**:
  - `resp`: Map (contains the "message" field of String type, which is the spliced greeting string, e.g., "Hello! World")

### 3.3. Write Logic and Code Implementation in Service Function
#### 3.3.1. Logical Steps:
1. Define a method named `hello` that returns a Map and takes a single parameter: `requestData` (Map type, compatible with POST request body/GET URL parameters).
2. Extract the "name" field from `requestData`; if the field is empty or not present, assign "World" as the default value.
3. Log an informational message using `IComposerSystem.info`, passing the string `"Hello :{}"` and the `name` parameter as arguments.
4. Concatenate the string "Hello! " with the `name` parameter to form the greeting message.
5. Encapsulate the greeting message into a Map with the key "message" and return this Map.

#### 3.3.2. Dependencies and Imports:
- Import third-party package: `IComposerSystem` from the iComposer built-in methods.
- Import Java util packages: `HashMap`, `Map`.
- No CommonServices are declared or used in this function.

#### 3.3.3. Define the **Method `hello`**:
- **Explanation**: This method accepts a `Map` parameter named `requestData`. It extracts the "name" field from the Map (assigning "World" as default if missing/empty), logs an informational message using the `info` method from `IComposerSystem` (including the `name`), constructs a greeting string, encapsulates it into a Map with the key "message", and returns the Map.
- **Service Function Invoked**: None
- **SDK Method Path Invoked**: None
- **RestTemplate API URL Invoked**: None

#### 3.3.4. Code Implementation:
```groovy
package Tenant.test_api.function.HelloWorldService;

import com.insuremo.icomposer.builtins.methods.IComposerSystem;
import java.util.HashMap;
import java.util.Map;

def hello(Map requestData) {
    // 1. Extract the "name" field and handle default value
    String name = null;
    if (requestData != null && requestData.get("name") != null) {
        name = requestData.get("name").toString();
    } else {
        name = "World"; // Default value
    }

    // 2. Print log
    IComposerSystem.info("Hello :{}", name);
    
    // 3. Encapsulate response into Map format
    String resultMsg = "Hello! " + name;
    Map<String, Object> resp = new HashMap<>();
    resp.put("message", resultMsg);
    
    // Return the encapsulated Map
    return resp;
}
```

Click `Save` to upload the information. `Exit` will discard all your edits.

### 3.4. Online Testing
Click `Online Testing` on the upper toll bar. Select `Method Name` on the right, then you will see auto-generated `Key` and `Value` records on the left.

![sf_ot_blank](./image/iComposer_quick_start_image/sf_ot_blank.png)

#### 3.4.1. Functional Testing
- Test Parameter Configuration:
  - Key: `requestData` (Map)
  - Value: `Amy`
- Test Result:
  - Response Body: `{"message":"Hello! Amy"}`

![sf_ot_result](./image/iComposer_quick_start_image/sf_ot_result.png)

#### 3.4.2. Empty Input Testing
- Test Parameter Configuration:
  - Key: requestData (Map)
  - Value: null
- Test Result:
  - Response Body: `{"message":"Hello! World"}`

![sf_ot_result blank](./image/iComposer_quick_start_image/sf_ot_result_blank.png)


## 4. RESTful API
This chapter tells new users: RESTful API is the external access entry of iComposer, and it will invoke the Service Function created in the previous chapter. Here we create two Hello World RESTful APIs to illustrate the **Request Method** of `POST` and `GET` respectively.

### 4.1. Create a New POST API
1. In the left menu of iComposer, locate **Restful API**.

![ra_overview_search](./image/iComposer_quick_start_image/ra_overview_search.png)

2. Users are advised to search the search bar for RESTful APIs that have been entered into the system. If no relevant RESTful API is found, a new one should be created.
3. Click `Add`, and you will see the following interface.

![ra_blank](./image/iComposer_quick_start_image/ra_blank.png)

4. Fill in the basic information (example):
   - API Name: `HelloWorldApi`
   - Description: `Demo REST API (POST) calling HelloWorldService`
   - Request Method: `POST`
   - API Path: `/v1/flow/HelloWorldApi`
   - Module: `Policy Admin`
   - Group: `test_api`

![post_info](./image/iComposer_quick_start_image/post-restful.png)

### 4.2. Define Input and Output Structures
- Request Type: Map (request body in JSON format)
- Response Type: Map (contains the "message" field of String type)
- The `name` parameter is passed via the POST request body (JSON format) and read using `IComposerSystem.getRequestBody()` in the code.

### 4.3. Bind the API to the Service Function
#### 4.3.1. Code Implementation:
```groovy
import com.insuremo.icomposer.builtins.methods.IComposerSystem;
import java.util.Map;

// 1. Get Service Function instance
HelloWorldService helloWorldService = (HelloWorldService) IComposerSystem.getCommonService("HelloWorldService");

// 2. Read POST request body
Map body = (Map) IComposerSystem.getRequestBody();

// 3. Print interface layer log
IComposerSystem.info("HelloWorldApi(POST) receive request body: {}", body);

// 4. Call the service function and explicitly cast to Map type
Map<String, Object> result = (Map<String, Object>) helloWorldService.hello(body);

// 5. Return the result of the service function directly
return result;
```

#### 4.3.2. Explanation

> - `HelloWorldService` already exists in the function list (Type=function), so you only need to obtain an instance via `IComposerSystem.getCommonService("HelloWorldService")`.
> - Log: The `IComposerSystem.info()` method is used to record runtime logs, which helps in debugging and tracking the request flow (e.g., recording the request body received by the API).
> - Return Value: The API directly returns the Map result returned by the Service Function (with the key "message") as JSON, ensuring a unified response format for the API.

![post-content](./image/iComposer_quick_start_image/post-content.png)

After completing the code writing, click `Save` to upload the content.

### 4.4. RESTful API Online Testing (POST Method)
Click `Online Testing` on the upper toll bar.

#### 4.4.1. Functional Testing

- Fill the Request Body: `{"name": "Amy"}`
- Operation Step: Click the `Test` button in the upper right corner of the screen.

![post-online-testing](./image/iComposer_quick_start_image/post-online-testing.png)

- Test Log:
  ```
  HelloWorldApi(POST) receive request body: {name=Amy}
  Hello : Amy
  ```
- Response Body:
  ```json
  {
    "message": "Hello!  Amy"
  }
  ```

![post-online-testing2](./image/iComposer_quick_start_image/post-online-testing2.png)




#### 4.4.2. Empty Input Testing

- Fill the Request Body: `{}`
- Operation Step: Click the `Test` button in the upper right corner of the screen.

![post-online-testing](./image/iComposer_quick_start_image/post-online-testing-blank.png)

### 4.5. HelloWorldApi RESTful GET Method
#### 4.5.1. RESTful API Basic Information
- API Path: `/v1/flow/HelloWorldApiGet`
- Request Method: GET
- Request Type: Map (URL query parameters)
- Response Type: Map (contains the "message" field of String type)
- Request Parameters: Query parameter `name`
- Logic:
  1. Retrieve the `name` parameter from the GET URL query parameters (via `IComposerSystem.getRequestParameter()`).
  2. Invoke `HelloWorldService.hello(requestParam)` (pass the query parameters Map to the service function).
  3. Return the Map result returned by the service function as the API response (ensuring a unified JSON format).

Input the above information, and click `Save` to upload.

![get-restful](./image/iComposer_quick_start_image/get-restful.png)

#### 4.5.2. Code Implementation (Groovy)
Create a new API in the RESTful API editing page of iComposer according to the above information, then write the following code in the Content area:
```groovy
import com.insuremo.icomposer.builtins.methods.IComposerSystem;
import java.util.Map;

// 1. Get Service Function instance
HelloWorldService helloWorldService = (HelloWorldService) IComposerSystem.getCommonService("HelloWorldService");

// 2. Read GET URL parameters
Map requestParam = (Map) IComposerSystem.getRequestParameter();

// 3. Print interface layer log
IComposerSystem.info("HelloWorldApi(GET) receive request params: {}", requestParam);

// 4. Call the service function and explicitly cast to Map type
Map<String, Object> result = (Map<String, Object>) helloWorldService.hello(requestParam);

// 5. Return the result of the service function directly
return result;
```

> Explanation
> - `HelloWorldService` already exists in the function list (Type=function), so you only need to obtain an instance via `IComposerSystem.getCommonService("HelloWorldService")`.
> - Log: The `IComposerSystem.info()` method records the GET query parameters received by the API, facilitating debugging; the service function itself logs the "Hello :{name}" message, so no additional log processing for the greeting is needed in the API code.
> - Return Value: The API returns the Map result from the Service Function as JSON (format: `{"message": "Hello! Amy"}`), which conforms to standard API response specifications.

![get-content](./image/iComposer_quick_start_image/get-content.png)

After completing the code writing, click `Save` to upload the content.

#### 4.5.3 Online Testing (GET Method)
##### 4.5.3.1. Functional Testing
- Fill the Request Parameter: `name= Amy`
- Operation Step: Click the `Test` button on the page.

![get-online-test1](./image/iComposer_quick_start_image/get-online-test1.png)

- Test Log:
  ```
  HelloWorldApi(GET) receive request params: {name=Amy}
  Hello : Amy
  ```
- Response Body:
  ```json
  {
    "message": "Hello!  Amy"
  }
  ```
![get-online-test2](./image/iComposer_quick_start_image/get-online-test2.png)

##### 4.5.3.2. Empty Input Testing

- Fill the Request Parameter: 
- Operation Step: Click the `Test` button in the upper right corner of the screen.

![post-online-testing](./image/iComposer_quick_start_image/get-online-testing-blank.png)