T24 Co m pon e n tisation RESTful WS
Ame n d m e n t Hist o ry:
Revi s i o
Dat e Ame n d e d Na m e De s c r i p t i o n
n
1 21 st June 2019 T. Auber t Initial version
2 1 st July 2019 T. Auber t Suppo r t of PUT, POST, DELETE and Secu ri ty
3 26 th Marc h 2020 H. Aube r t R20 AMR Review
Bashe e r
4 12 th April 2021 R21 AMR review
Aham e d
5 25 th Marc h 2022 S.Sakt hi R22 AMR Review
Corr e c t @GET Annota tio n refer e n c e s as
6 3 rd Marc h 2022 Riswa n a
FUNCTION
7 6 rd April 2023 M. Kuma r R23 AMR Review
2
T24 Co m pon e n tisation RESTful WS
Copyri g h t
Copyrig h t © Teme n o s Hea d q u a r t e r s SA 2009- 2023.
All right s rese rv e d.
This docu m e n t cont ain s prop rie t a r y inform a tio n that is prote c t e d by copyrig h t. No part of this docu m e n t may
be repro d u c e d , tra ns m i t t e d , or mad e availa ble direc tly or indirec tly to a third party without the expr e s s
writt e n agre e m e n t of TEMENOS UK Limite d. Receipt of this mate ri al direc tly TEMENO S UK Limite d
constit u t e s its expr e s s per mis sion to copy. Per mis sion to use or copy this docu m e n t expr e s sly exclud e s
modifying it for any purpo s e , or using it to cre a t e a derivative the r ef ro m .
Errat a and Com m e n t s
If you have any com m e n t s reg a r di n g this man u al or wish to repor t any error s in the docu m e n t a t i o n ,
plea s e docu m e n t the m and send the m to the add r e s s below:
Technology Depa r t m e n t
Teme no s Hea d q u a r t e r s SA
2 Rue de l’Ecole- de- Chimie,
CH - 1205 Geneva,
Switze rl a n d
Tel SB: +4 1 (0) 22 708 1150
Fax: +4 1 (0) 22 708 1160
Pleas e includ e your na m e , comp a n y, addr e s s, and telep h o n e and fax num b e r s , and email add r e s s if
applica bl e. TAFJdev@t e m e n o s . c o m
3 Teme no s Application Fra m e w o r k Java – (TAFJ)
T24 Co m pon e n tisation RESTful WS
Table of Conte n t s
4
T24 Co m pon e n tisation RESTful WS
Intro d u c t i o n
This docu m e n t descri b e how to crea t e RESTful webs e r vic e s using the T24 Compo n e n t Fra m e w o r k . This
neve r bee n easie r to gene r a t e such servic e s. In fact, this can be done in a secon d. All the compl exiti es
are handl e d by the compo n e n t fram e w o r k and its new function ality: the annot a t i o n s.
The targ e t audi e n c e
The rea d e r of this docu m e n t shoul d alre a dy be familiar with the JBC langu a g e and the compo n e n t
fram e w o r k (*.com po n e n t and *.complex). We will go throu g h exa m pl e s and will conc e n t r a t e on the
RESTful webs e r vic e s gene r a t io n. Also, we will use “post m a n “ to use our servic e.
Get ready
First, we will cre a t e a new com po n e n t with a simpl e met ho d.
Com po n e n t na m e : MY.FirstR e s t
Met ho d : getE m pl oy e e( Fi r s t N a m e , Last N a m e )
component MY.FirstRest
/* return employee lastName */
private method getEmployee : String(
/* The first name */
IN firstName string,
/* The lastName */
OUT lastName string
)
{
jBC: GET.EMPLOYEE
}
and imple m e n t the met h o d GET.EMPLOYEE :
$PACKAGE MY.FirstRest
*
* Implementation of MY.FirstRest.getEmployee
*
* firstName(IN) :
* lastName(OUT) :
*
FUNCTION GET.EMPLOYEE(firstName, lastName)
IF firstName = "Tony" THEN
lastName = "Curtis"
END ELSE
5 Teme no s Application Fra m e w o r k Java – (TAFJ)
T24 Co m pon e n tisation RESTful WS
lastName = "Unknown"
END
RETURN
By saving, the compo n e n t is auto m a ti c ally compile d, pack a g e d and you can find a file MY_FirstR e s t .ja r in
the direct o r y <t afj_hom e > / d a t a / < p r o j e c t N a m e > / j a r s .
Let’s assu m e you have a jboss app serve r, then deploy this file (in modul e) and upd a t e your modul e.x ml :
<module xmlns="urn:jboss:module:1.0" name="com.temenos.t24">
<resources>
<!-- Insert resources here -->
<resource-root path="./services/MY_FirstRest.jar" />
Then rest a r t your app serve r. This is nee d e d since this is a module, not a service (yet).
6
T24 Co m pon e n tisation RESTful WS
The first RESTf ul web s e r v i c e
In orde r to crea t e a webs e r vic e from your met ho d, only one oper a ti o n is nee d e d :
add the “@GET” annot a t i o n to your met ho d like this and save your .compo n e n t .
component MY.FirstRest
/* return employee lastName */
@GET
private method getEmployee : String(
/* The first name */
IN firstName string,
/* The lastName */
OUT lastName string
)
{
jBC: GET.EMPLOYEE
}
!! Thi s is it, con g r a t u l a t i o n , you cre a t e d your first RESTf u l
web s e r v i c e !!!
If you look in your jars direc t o ry, you now have a new file : my- firstr e s t . w a r . Ther e is a kind of
conve n t ion in the web service s : The URI should be lower case, and the unde r s c o r e should be repla c e d by
“-”. This is what we are doing her e. To deploy it, just copy this file in your app serve r
(<jboss_ho m e > / s t a n d a l o n e / d e p l oy m e n t s ). You don’t nee d to rest a r t your app serve r, it will dete c t and
load auto m a t i c a lly your service.
Test it with post m a n :
The URI of th e servi c e s
The URI is the part after the
<p r o t o c ol > : // < h o s t > : < p o r t > . In our
case : “/my- first r e s t / e m p l oy e e /Tony”
is compos e d of :
1) /my- firstr e s t : the root_pa t h (the nam e of the war file inhe rit e d from the na m e of your .com po n e n t )
2) /e m p l o y e e : The Servic e na m e (the nam e of your met ho d in lower c a s e without the “get”)
3) The “IN” / “INOUT” para m e t e r s of your met ho d
We will see later in this docu m e n t how we can modify the m .
7 Teme no s Application Fra m e w o r k Java – (TAFJ)
T24 Co m pon e n tisation RESTful WS
Note that all service s crea t e d with the T24 com po n e n t Fra m e w o r k have one met h o d ( servi c e s ) which
will show you all the URIs :
So you this URI : /my- first r e s t / servi c e s will list all the availabl e URIs like this (html outp u t) :
8
T24 Co m pon e n tisation RESTful WS
The stru c t u r e of th e res p o n s e
The respo n s e will always have the JSON form a t .
The default respo n s e struc t u r e is :
{
"root": {
"<OUT / INOUT parameters>": "<value>"
"response": <return value of the jBC Function>
}
}
@Re s p o n s e ( … ) an n o t a t i o n
The above struc t u r e of the respo n s e can be modified by using the @Respo n s e annot a t io n. To desc ri b e it,
edit your com po n e n t like this :
component MY.FirstRest
/* return employee lastName */
@GET
@Response("my.new.response.structure")
private method getEmployee : String(
...
}
URL : htt p://loc al ho s t : 9 0 8 9 / my- first r e s t /employe e /To ny
{
"my": {
"new": {
"response": {
"lastName": "Curtis"
}
}
}
}
Chan g i n g th e def a u l t be h a v i o u r s .
Appar t chan gi n g the root path (the nam e of the war file) mostly everyt hi n g can be modified using
annot a ti o n s. In this cha pt e r we will see how.
@Pat h (…) an n o t a t i o n (co m p o n e n t lev e l )
The com po n e n t can be annot a t e d with a @Pat h. The defa ult value is “/”
Exam pl e :
@Path("/training/rest")
component MY.FirstRest
9 Teme no s Application Fra m e w o r k Java – (TAFJ)
T24 Co m pon e n tisation RESTful WS
/* return employee lastName */
@GET
@Response("my.new.response.structure")
private method getEmployee : String(
/* The first name */
IN firstName string,
/* The lastName */
OUT lastName string
)
{
jBC: GET.EMPLOYEE
}
Cha n g e s the URI to : /my- firstr e s t / traini n g/ r e s t / employe e/ {fi r st N a m e }
@Pat h (…) an n o t a t i o n (m e t h o d leve l )
Each met ho d s can also have the @Pat h annot a t i o n. The default is
/< m e t h o d N a m e _ wi t h o u t_g e t > / { a l l IN/INOUT par a m e t e r s }
In our case, “/em ploye e / {fi r s t N a m e } ”
If the met ho d had bee n
private method getEmployee : String(
IN country string,
IN city string,
IN firstName string,
OUT lastName string
)
The URI would have bee n “/em ploye e / { c o u n t r y } / { c i ty }/ {fir s t n a m e } ”
You can chan g e the defa ult with the @Pat h annot a t i o n for the met ho d. At that point ther e is a lot of
validatio n being done at the com po n e n t fram e w o r k level.
First, let’s chan g e it like this :
@Path("/training/rest")
component MY.FirstRest
/* return employee lastName */
@GET
@Response("my.new.response.structure")
@Path("/temenos/person/{firstName}/name")
private method getEmployee : String(
...
}
So the URI is now : my- firstr e s t / t r a i n i n g / r e s t / te m e n o s /per s o n /Tony /na m e
Validation (rules) for the @Pat h annot a ti o n :
1) All IN, INOUT, MEMBER variabl e s, if not annot a t e d as @Que ryP a r a m must be in the Path.
2) All {…} variabl e s must exist s in the definition of the met ho d
10
T24 Co m pon e n tisation RESTful WS
3) If a variabl e is annot a t e d with @QueryP a r a m , it cannot be in the @Pat h.
Befor e going in exam pl e s, let’s desc ri b e the @QueryP a r a m …
11 Teme n o s Application Fra m e w o r k Java – (TAFJ)
T24 Co m pon e n tisation RESTful WS
@Query P a r a m ( … ) an n o t a t i o n
Each (not OUT) variabl e can be annot a t e d by the @Que ryP a r a m annot a t io n. The @Que ryP a r a m
annot a ti o n indica t e s that the par a m e t e r is not part of the URI anymo r e , but inste a d in the html que ry
par a m e t e r . E x a m p l e :
@Path("/training/rest")
component MY.FirstRest
/* return employee lastName */
@GET
@Response("my.new.response.structure")
@Path("/temenos/person")
private method getEmployee : String(
/* The first name */
@QueryParam
IN firstName string,
. . .
}
Make s that the http requ e s t is now :
http://localho s t : 9 0 8 9/ m y- first r e s t/ t r a i ni n g/ r e s t / t e m e n o s / p e r s o n ?first N a m e = T o n y
Multipl e QueryP a r a m s are sepa r a t e d by “&”. eg : … ?first N a m e = T o n y & c o u n t r y = U K ….
A QueryP a r a m can have an alias. Exam pl e : @QueryP a r a m ( “ nam e ”) will make the requ e s t :
http://localho s t : 9 0 8 9/ m y- first r e s t/ t r a i ni n g/ r e s t / t e m e n o s / p e r s o n ? nam e =Tony
Let’s resu m e the @Pat h & @QueryP a r a m like this.
Component definition http://localho s t : 9 0 8 9/ my- f irstr e s t ….
private method getEmployee :
.../ e m p l o y e e / { c o u n t r y } / { c i t y } / { f i r s t N a m e }
String(
IN country string,
IN city string,
IN firstName string,
OUT lastName string
)
@Path("/{country}/{city}") Compilation error :
private method getEmployee :
String( MY.FirstRest.component, The variable
firstName must be either in the @Path
IN country string,
annotation or must be annotated as
IN city string, '@QueryParam'
IN firstName string,
OUT lastName string
)
@Path("/xxx/{country}/{city}")
.../xxx/ { c o u n t r y } / { c i t y } ? n a m e = ….
12
T24 Co m pon e n tisation RESTful WS
private method getEmployee :
String(
IN country string,
IN city string,
@QueryParam("name")
IN firstName string,
OUT lastName string
)
@Path("/{country}/{city}") Compilation error :
private method getEmployee :
MY.FirstRest.component, The variable
String(
city cannot be a @QueryParam as it is
IN country string, already in the @Path : '/{country}/
@QueryParam("town") {city}'
IN city string,
@QueryParam("name")
IN firstName string,
OUT lastName string
)
@Path("/{country}/{lastName}") Compilation error :
private method getEmployee :
MY.FirstRest.component, The variable
String(
lastName cannot be in the @Path as it is
IN country string, a 'OUT' variable.
@QueryParam("town")
IN city string,
@QueryParam("name")
IN firstName string,
OUT lastName string
)
@Path("/{country}") Compilation error :
private method getEmployee :
MY.FirstRest.component, The variable
String(
lastName cannot be a @QueryParam as it
IN country string, is a 'OUT' variable.
@QueryParam("town")
IN city string,
@QueryParam("name")
IN firstName string,
@QueryParam("familly")
OUT lastName string
)
13 Teme n o s Application Fra m e w o r k Java – (TAFJ)
T24 Co m pon e n tisation RESTful WS
@Path("/{country}")
.../ { c o u n t r y } ? t o w n = ….&na m e = . . .
private method getEmployee :
String(
IN country string,
@QueryParam("town")
IN city string,
@QueryParam("name")
IN firstName string,
OUT lastName string
)
private method getEmployee :
.../ { c i t y } ? c o u n t r y = ….&na m e = …
String(
@QueryParam("country") Not e : If no @Path specifie d, all variable not
having the QueryPara m will be in the URI
IN country string,
IN city string,
@QueryParam("name")
IN firstName string,
OUT lastName string
)
14
T24 Co m pon e n tisation RESTful WS
Ret ur n valu e (FU NCTIO N s )
Let’s first get back to our favourit e compo n e n t , an modify the getE m pl oy e e met ho d like this :
component MY.FirstRest
/* return employee lastName */
@GET
private method getEmployee : string (
/* The first name */
IN firstName string
)
{
jBC: GET.EMPLOYEE
}
And the Imple m e n t a t i o n :
$PACKAGE MY.FirstRest
*
* Implementation of MY.FirstRest.getEmployee
*
* firstName(IN) :
*
FUNCTION GET.EMPLOYEE(firstName)
IF firstName = "Tony" THEN
RETURN "Curtis"
END ELSE
RETURN "Unknown"
END
RETURN
Reme m b e r that you nee d to rest a r t your app serve r !
15 Teme n o s Application Fra m e w o r k Java – (TAFJ)
T24 Co m pon e n tisation RESTful WS
Result :
As mentionned earlier, the « default » structure of the response is root.response. Please refer to the specific
chapter if you want to modify it. Unlike the OU / INOUT variables, the response can be a list<...> a complex
type or a list<complex type>.
Let’s first see what happen with lists. Modify you implementation like this :
component MY.FirstRest
/* return employee lastName */
@GET
private method getEmployee : list<string> (
/* The first name */
IN firstName string
)
{
jBC: GET.EMPLOYEE
}
FUNCTION GET.EMPLOYEE(firstName)
$USING TF.List
RET = ""
IF firstName = "Tony" THEN
TF.List.add(RET, "Curtis")
TF.List.add(RET, "Stark")
TF.List.add(RET, "Blair")
TF.List.add(RET, "Parker")
END ELSE
RETURN "Unknown"
END
RETURN RET
Redeploy MY_FirstRest.jar and my-firstrest.war and restart your app server.
The same query now returns an array :
16
T24 Co m pon e n tisation RESTful WS
Ret u r n i n g co m p l e x stru c t u r e s
Here we will (again) modify our component and implementation to return a complex structure. To do so, create
a new Complex and edit it like this :
complex Employee
@Containment byValue
classes {
NameAndAge
{
lastName : string
age : number
}
}
17 Teme n o s Application Fra m e w o r k Java – (TAFJ)
T24 Co m pon e n tisation RESTful WS
Then, modify your component like this :
component MY.FirstRest
/* return employee lastName */
@GET
private method getEmployee : list<Employee:NameAndAge> (
/* The first name */
IN firstName string
)
{
jBC: GET.EMPLOYEE
}
And your implementation like this :
$PACKAGE MY.FirstRest
*
* Implementation of MY.FirstRest.getEmployee
*
* firstName(IN) :
*
FUNCTION GET.EMPLOYEE(firstName)
$USING TF.List
RET = ""
IF firstName = "Tony" THEN
TF.List.add(RET, "Curtis" : @FM : 85)
TF.List.add(RET, "Stark" : @FM : 53)
TF.List.add(RET, "Blair" : @FM : 66)
TF.List.add(RET, "Parkers" : @FM : 37)
END ELSE
RETURN "Unknown"
END
RETURN RET
Redeploy the war and the jar, restart your app server, and redo the same request :
18
T24 Co m pon e n tisation RESTful WS
19 Teme n o s Application Fra m e w o r k Java – (TAFJ)
T24 Co m pon e n tisation RESTful WS
PUT, POST and DELETE
@PUT, @POST and @DELETE are supported exactely the same way as the @GET described earlier.
There is however few differences.
- @DELETE follows exactly the same validation rules as @GET
- @PUT & @POST are supporting, in addition to the @QueryParam, the @FormParam. The validation rules
(no duplicates, not in the @Path, …) are exactely the same.
Se c u r i t y
You method can be annotated with the standard following security annotations
RolesAllowed(...)
DeclareRoles(...)
DenyAll
PermitAll
RunAs(...)
20