Add functions to the service module
Define resources to create, update, and delete customers.
In this task you add functions to the Genero BDL module created in Create a web service module to define new resources for inserting (POST), updating (PUT), and deleting (DELETE) customers.
-
Open your service module: myservice.4gl
Define the following record at the modular level for handling application level errors:
PUBLIC DEFINE userError RECORD ATTRIBUTES(WSError="User error") message STRING END RECORD
-
Add a function to insert a customer row in the database (copy and paste the code below)
In the function's
ATTRIBUTES
clause the following attributes are set:- WSPost – specifies the POST HTTP verb
- WSPath – specifies the resource endpoint.
- WSDescription – provides a description of the resource which will be displayed in the generated openAPI specification file.
- WSThrows – is set to handle errors. We
trap errors in the
TRY/CATCH
block. We check theSQLCA
record after the execution of the SQL query. We set theSQLERRMESSAGE
to themessage
field of theuserError
variable and call toSetRestError()
to return the message defined inWSThrows
for the error.
In the function's input parameter we provide the new customer's details in the
thisCustomer
variable of typecustinfoType
.In the function'sRETURNS
clause, we return the new customer id in thepkey
variable.PUBLIC FUNCTION createCustomer( thisCustomer custinfoType) ATTRIBUTES(WSPost, WSPath = "/customers", WSDescription = "Create a new Customer", WSThrows = "400:@userError") RETURNS INTEGER DEFINE pkey INTEGER TRY LET thisCustomer.cust_yts = CURRENT # cust_num is a serial type, with syntax below, the serial column # is not used. See fglcomp -S output for generated INSERT INSERT INTO custinfo VALUES thisCustomer.* # get the serial number created for the primary key LET pkey = sqlca.sqlerrd[2] CATCH LET userError.message = SFMT("SQL error:%1 [%2]", sqlca.sqlcode, SQLERRMESSAGE) CALL com.WebServiceEngine.SetRestError(400, userError) LET pkey = NULL END TRY RETURN pkey END FUNCTION
-
Create a function to update a customer's details (copy and paste the code below)
In the function's
ATTRIBUTES
clause the following attributes are set:- WSPut – specifies the PUT HTTP verb.
- WSPath – specifies the resource endpoint.
- WSDescription – provides a description of the resource which will be displayed in the generated openAPI specification file.
- WSThrows – is set to handle request errors.
In the function's input parameter we set the attribute WSParam to specify the customer id.PUBLIC FUNCTION updateCustomer( resourceId INTEGER ATTRIBUTES(WSParam), thisCustomer custinfoType) ATTRIBUTES(WSPut, WSPath = "/customers/{resourceId}", WSDescription = "Update Customer info", WSThrows = "400:@userError") RETURNS STRING DEFINE ret STRING TRY LET thisCustomer.cust_yts = CURRENT UPDATE custinfo SET cust_fname = thisCustomer.cust_fname, cust_lname = thisCustomer.cust_lname, cust_addr = thisCustomer.cust_addr, cust_email = thisCustomer.cust_email, cust_yts = thisCustomer.cust_yts, cust_rate = thisCustomer.cust_rate, cust_comment = thisCustomer.cust_comment WHERE cust_num = resourceId # sqlca.sqlerrd[3] field gives the number of rows updated. IF sqlca.sqlerrd[3] == 1 THEN LET ret = SFMT("Updated customer: %1", resourceId) ELSE LET ret = SFMT("Customer not found: %1", resourceId) END IF CATCH LET userError.message = SFMT("SQL error:%1 [%2]", sqlca.sqlcode, SQLERRMESSAGE) # 400 is defined by the WSThrows attribute CALL com.WebServiceEngine.SetRestError(400, userError) END TRY RETURN ret END FUNCTION
-
Create a function to delete a customer (copy and paste the code below)
In the function's
ATTRIBUTES
clause the following attributes are set:- WSDelete – specifies the DELETE HTTP verb.
- WSPath – specifies the resource endpoint.
- WSDescription – provides a description of the resource which will be displayed in the generated openAPI specification file.
In the function's input parameter we set the attribute WSParam to specify the customer to delete.
PUBLIC FUNCTION deleteCustomer( resourceId INTEGER ATTRIBUTES(WSParam)) ATTRIBUTES(WSDelete, WSPath = "/customers/{resourceId}", WSDescription = "Delete a Customer") RETURNS STRING DEFINE ret STRING DELETE FROM custinfo WHERE cust_num = resourceId IF sqlca.sqlerrd[3] == 1 THEN LET ret = SFMT("Deleted customer id = %1", resourceId) ELSE LET ret = SFMT("Customer %1 not found ", resourceId) END IF RETURN ret END FUNCTION
-
Create a function to get customer keys (copy and paste the code below)
In the function's
ATTRIBUTES
clause the following attributes are set:- WSGet – specifies the GET HTTP verb.
- WSPath – specifies the resource endpoint.
- WSDescription – provides a description of the resource which will be displayed in the generated openAPI specification file.
In the function's
RETURNS
clause the array returns a list of customer keys.PUBLIC FUNCTION getCustomerRecordKeys() ATTRIBUTES(WSGet, WSPath = "/customerkeys", WSDescription = "Fetches all Customer primary keys.") RETURNS(DYNAMIC ARRAY OF INTEGER) DEFINE i INTEGER = 1 DEFINE keys DYNAMIC ARRAY OF INTEGER DECLARE customerCurKeys CURSOR FOR SELECT cust_num FROM custinfo ORDER BY cust_lname FOREACH customerCurKeys INTO keys[i] LET i = i + 1 END FOREACH # Remove last element implied by reference in FOREACH loop CALL keys.deleteElement(keys.getLength()) RETURN keys END FUNCTION