White Papers
Abstract
Tom Baranski
Senior Software Engineer
The EGL language enables applications deployed on various target platforms to be accessible as REST web services. The target platform can be an application server, a local machine, a CICS Transaction Server or a Docker environment.
This paper details the methods in which EGL applications running on a local machine can be accessed as a REST service, using the Spring Framework.
Content
Introduction
Representational State Transfer (REST) web services are services that can be invoked using HTTP. The service provides access to a web resource that is specified in a URI. The service’s operations correspond to HTTP operations, four of which are supported in EGL:
- GET – for retrieving resources
- POST – for creating resources
- PUT – for creating or updating resources
- DELETE – for deleting resources
- An EGL service part, which describes the operations made available with REST and the parameters that are passed.
- An EGL Deployment Descriptor, which describes how to deploy the EGL REST service to a target platform.
- The EGL serviceLib Library, which provides a set of functions for customizing and processing the REST invocation and response.
In EGL, a REST service’s URI is split into two components:
- A base URI, which is the leading part of the URI and is usually the address of the REST service
- A URI template which is the trailing part of the URI and is usually the name of the service and the parameters of the service.
At run time, the base URI and URI template are concatenated to form the complete URI for invocation. This means that it is also possible to have the full URI in either the baseURI or the URI
http://www.example.com/myservice?q={myquery}&numReturnRows={rowCount}
Then the base URI is http://ww.example.com and the URI Template is /myservice?q={myquery}&numReturnRows={rowCount}.
- IBM Rational Business Developer (RBD).
- Knowledge of developing services using EGL and RBD.
- Knowledge of Spring Framework and OpenAPI/Swagger documentation
Functions in an EGL Service are mapped to a REST operation using the @Rest annotation. There are four types of @Rest annotations that are available, which correspond to the four main REST operations:
- @GetRest
- @PutRest
- @PostRest
- @DeleteRest
package services;
record employee type sqlrecord{description = "everything you need to know about an employee",tableNames =[["SAMP.EMPLOYEE"]
], fieldsMatchColumns = yes,keyItems = [empno]}
empno string{column = "EMPNO", maxLen = 6};
firstnme string{column = "FIRSTNME", sqlVariableLen = yes, maxLen = 12};
midinit string{column = "MIDINIT", maxLen = 1};
lastname string{column = "LASTNAME", sqlVariableLen = yes, maxLen = 15};
workdept string{column = "WORKDEPT", isSqlNullable = yes, maxLen = 3};
phoneno string{column = "PHONENO", isSqlNullable = yes, maxLen = 4};
hiredate date{column = "HIREDATE", isSqlNullable = yes, description = "employee's hire date"};
job string{column = "JOB", isSqlNullable = yes, maxLen = 8};
edlevel smallInt{column = "EDLEVEL"};
sex string{column = "SEX", isSqlNullable = yes, maxLen = 1};
birthdate date{column = "BIRTHDATE", isSqlNullable = yes};
salary decimal(9, 2){column = "SALARY", isSqlNullable = yes};
bonus decimal(9, 2){column = "BONUS", isSqlNullable = yes};
comm decimal(9, 2){column = "COMM", isSqlNullable = yes};
end
service service1{Title = "Employee Service", description = "Operates On The Employee Database", version = "1.0.0"}
function getEmployee(empno string in) returns(employee){tags =[
"employeeRecord", "retrieveEmployee"
], description = "gets an existing employee", @GetRest{uriTemplate = "/employee/{empno}", responseFormat = JSON}}
myemp employee;
myemp.empno = empno;
get myemp;
if(myemp is norecordfound)
nfresp HttpResponse;
nfresp.status = 404;
nfresp.body = "Employee " + empno + " Not Found";
serviceLib.setRestResponse(nfresp);
end
return(myemp);
end
function addEmployee(emp employee in){tags =["employeeRecord",
"modifyEmployee"
], description = "adds a new employee", @PostRest{uriTemplate = "/newemployee", requestFormat = JSON}}
add emp;
end
function updateEmployee(emp employee in){tags =["employeeRecord",
"modifyEmployee"
], description = "updates an existing employee", @PutRest{uriTemplate = "/changeemployee", requestFormat = JSON}}
get emp forUpdate;
if(emp is norecordfound)
nfresp HttpResponse;
nfresp.status = 404;
nfresp.body = "Employee " + emp.empno + " Not Found";
serviceLib.setRestResponse(nfresp);
else
replace emp;
end
end
function deleteEmployee(empno string in){tags =[
"employeeRecord", "modifyEmployee"
], description = "deletes an existing employee", @DeleteRest{uriTemplate = "/removeemployee/{empno}"}}
myemp employee;
myemp.empno = empno;
get myemp forUpdate;
if(myemp is norecordfound)
nfresp HttpResponse;
nfresp.status = 404;
nfresp.body = "Employee " + empno + " Not Found";
serviceLib.setRestResponse(nfresp);
else
delete myemp;
end
end
end
This property allows the user to parameterize the URI. Each parameter in the URI corresponds to a parameter defined in the function. At run time, the values of the parameters are substituted into the URI, which is then appended to the base URI to create the full URI needed to invoke the service.
requestFormat
This property specifies how the request data is to be formatted when sent to the REST service. There are four formats available in EGL:
- NONE – the request data is sent as a string
- XML – the request data is an EGL record, which is converted at run time to XML
- JSON – the request data is an EGL record, which is converted at run time to JSON
responseFormat
This property specifies the format that the REST service uses to send back data. There are three formats that EGL can understand
- NONE – the response data is a raw string that is sent to the EGL client as-is
- XML – the response data is an XML formatted string that is to be converted to an EGL record
- JSON – the response data is a JSON formatted string that is to be converted to an EGL record
Documenting the REST Service
EGL provides additional annotations for documenting REST Services. This is used for generating the OpenAPI document that defines the REST Service.
This includes:
This is the title of the OpenAPI document
Description
A brief description of the service, operation or record
Version
A user-defined version number of the service
Tags
Allows the service operations to be grouped by keyword(s) in the OpenAPI document
Preferences For Documenting the REST Service
Figure 2: Preferences for OpenAPI generation
OpenAPI Version controls the format of the generated OpenAPI document. Default is OpenAPI-3.0, but you can also select OpenAPI-2.0 (also known as Swagger specification).
Step 2: Go to the Service Deployment tab and click Add .
Step 3: Select Generate as: REST Service and add the EGL Service you wish to deploy as a REST service and click ‘Finish’
Step 4: If desired, set the URI under REST Web Service Properties. This is the baseURI that the service will be available at. The default value is the service name. The uriTemplate is appended to this to create the invocable URI e.g. http://localhost:8080/service1/employee/{empno}
Step 2: Open the EGL Deployment Descriptor for your project.
Step 3: Go to the Overview tab, and set the Deployment Target to be the build descriptor from step 1.
Step 4: Right click on the deployment descriptor, and select Deploy EGL Descriptor.
Step 5: Add the Spring libraries to the Java build path for the target genProject. These libraries are provided for you in the directory: RBD_SHARED_DIR/plugins/com.ibm.etools.egl.rui.deploy.j2ee\lib\eglspring_lib.zip
serviceLib.setRestResponse(response HttpResponse in)
The response body to be returned from the service;
- body contains the value in one of three formats (XML, JSON, or NONE), as described in “REST for the developer.”
- If body is not specified, then the value of body will be the function response in one of three formats (XML, JSON, or NONE)
headers, type Dictionary
headers contains a set of name-value pairs. Each entry key in the dictionary is the name of an HTTP header that is to be returned from the service, and the related value (a string) is the value of that header.
status, type INT
status contains the HTTP status code for the response. If status is not specified, then the value 200 is used.
Important status codes include 200 (OK) and 404 (Not Found). For a complete list, go to the website of the World Wide Web Consortium (http://www.w3.org/) and search for "HTTP status code.".
statusMessage, type STRING
statusMessage contains the HTTP status message for the response. If statusMessage is not specified, then the value OK is used.
Important status messages include OK (code 200) and Not Found (code 404). For a complete list, go to the website of the World Wide Web Consortium (http://www.w3.org/) and search for "HTTP status code."
Was this topic helpful?
Document Information
Modified date:
16 February 2023
UID
ibm16587457