Building the "Order Management" Training App : Creating a custom REST endpoint
Prerequisite : You have a basic understanding of the Simplicité platform, and the steps in Enhancing are completed
What is a custom web service ?
By default, for each object, Simplicité exposes default REST endpoints. Sometimes, the default REST endpoints don't cover the business requirements, custom web services can be created with External Objects. An External Object can be used to implement a specific UI component, a custom front-end, a specific web service... Learn more
Creating an endpoint to retrieve the List of Suppliers
Let's say we want to call a custom endpoint that returns a list of Suppliers like so :
{
"found": true, // false if no results
"suppliers": [
{
"code": <supplier code>
"name": <supplier name>
"nbPrdInStock": <nb of products in stock>
},
...
]
}
To create a custom endpoint, follow the steps below :
- In the User interface > External Objects > Rest web service menu, click Create
- Fill in the form like so :
- Code : TrnWebService
- Nature : REST web service
- Click Save
Making the endpoint public
In the Permissions panel linked to the External Object :
- Click Create
- In the Primary group field, click
+
to create a new Group
- Fill in the Group fields like so :
- Name : TRN_PUBLIC
- Module Name : Training
- Click Save & Close to create the new Group
- Click Save & Close on the
Create Permission
form to create the Permission
The Endpoint is now granted to the users with the TRN_PUBLIC
Responsibility
Implementing the web service GET method
- Click Edit code
- Select
Java
, and click Confirm
Implement the TrnWebService
Class like so :
package com.simplicite.extobjects.Training;
import java.util.*;
import org.json.*;
import com.simplicite.util.*;
import com.simplicite.util.exceptions.*;
import com.simplicite.util.tools.*;
/**
* REST service external object TrnWebService
* This class implements a custom REST endpoint to retrieve supplier information including product counts
*/
public class TrnWebService extends com.simplicite.webapp.services.RESTServiceExternalObject {
private static final long serialVersionUID = 1L;
/**
* GET method handler that returns a list of suppliers with their product counts
* The response format is:
* {
* "found": boolean, // true if suppliers found, false otherwise
* "suppliers": [ // array of supplier objects
* {
* "code": string, // supplier code
* "name": string, // supplier name
* "nbPrdInStock": number // count of products in stock for this supplier
* }
* ]
* }
* @param params Request parameters (not used in this implementation)
* @return JSONObject containing supplier data
* @throws HTTPException if there is an error processing the request
*/
@Override
public Object get(Parameters params) throws HTTPException {
// Get grant and supplier object
Grant g = getGrant();
ObjectDB supplier = g.getIsolatedObject("TrnSupplier");
// Initialize response object with empty results
JSONObject results = new JSONObject()
.put("found", false)
.put("suppliers", new JSONArray());
// Search for all suppliers
List<String[]> rslts = supplier.search(false);
if (rslts.isEmpty()) {
return results; // Return early if no suppliers found
}
// Update found flag and get suppliers array
results.put("found", true);
JSONArray suppliers = results.getJSONArray("suppliers");
// Process each supplier
for (String[] row : rslts) {
supplier.setValues(row);
try {
// Create supplier object with code, name and product count
suppliers.put(new JSONObject()
.put("code", supplier.getFieldValue("trnSupCode"))
.put("name", supplier.getFieldValue("trnSupName"))
.put("nbPrdInStock", countPrdInstock(supplier.getRowId())));
} catch (SearchException e) {
// Log error if product count fails for a supplier
AppLog.error("Error counting products in stock for supplier " + supplier.getFieldValue("trnSupCode"), e);
}
}
return results;
}
/**
* Helper method to count products in stock for a supplier
* Counts only products with stock > 0
* @param supRowId Supplier row ID to count products for
* @return Number of products in stock for the supplier
* @throws SearchException If the product search fails
*/
private long countPrdInstock(String supRowId) throws SearchException {
// Create filter for products with stock > 0 belonging to supplier
JSONObject filters = new JSONObject().put("demoPrdSupId", supRowId).put("demoPrdStock", "> 0");
return getGrant().getIsolatedObject("TrnProduct").getTool().count(filters);
}
}
Adding the TRN_PUBLIC Group to public
user
Since the endpoint is available without authentication we need to add the TRN_PUBLIC responsibility to public
:
- In Users and rights > Users > Show all, open
public
- In the Responsibility panel, click Associate and associate the TRN_PUBLIC Group
Granting READ ONLY rights to TRN_PUBLIC
For both the TrnSupplier
and TrnProduct
object, grant TRN_PUBLIC to the READ Functions
- In Business objects > Business objects open the object
- In the Functions panel, open the Read only Function, click Associate and associate the TRN_PUBLIC Group
Test the endpoint
Public endpoints are available on <base_url>/api/ext/<External Object Name>
Clear the platform's cache and call the endpoint via Postman or curl
$ curl <instance_url>/api/ext/TrnWebService
> {"found":true,"suppliers":[{"code":"BIM","nbPrdInStock":1,"name":"Bim Computers Ltd."}]}