We will closely examine a very simplistic web service line by line here.

Hello World Example

Line 1: This example is coded in totally free RPG (**FREE).

Line 3: Depending on how we compile the program we can add some compile options here. For such a simple program it is ok to put the compile options into the source code. By doing that we can create the program in one step by using the compile command CRTBNDRPG.

On every serious project I would stay away from putting the compile options in the source code. You don’t want to change the source code if you just want to change a simple compile parameter (like the debug views) because a change in the program would mean you would have to test the whole program / workflow again even though nothing really changed. Use a build tool for building the project (f. e. make or any real change management system). Another very important pro for putting the compile options not in the code is when you want to change a compile option for the whole project. Then you would have to change it in every source. But with the compile options outside the source you can change it in one place for the whole application.

The binding directory (bnddir) in the compile options tells the compiler where to look for all the procedures not included in the source code, f. e. the procedures from the ILEastic service program.

We also declared that the compiler should make this whole module thread safe and allow concurrent access (multiple threads) to everything in this module (variables, procedure, …).

Line 5: This include statement includes all necessary stuff from the ILEastic copybook into our source code like prototypes, constants and data structure templates.

Line 9: The first thing we do here is to go into a local main procedure. We do this to avoid using global variables. Now the config variable is scoped to the main procedure and is no global variable. Whenever you can avoid using global variables, do it. Though for some things the compiler still expects global declarations, f. e. compile time arrays and data areas.

As we are immediately branching into the main procedure we could have used the main keyword in the control options. That would work but by using the main keyword we are also forfeiting the default RPG error handler and I like to have it. So by immediately calling the main procedure we can have best of both worlds.

Line 16: Here we configure on which port the web service will be listening on (which will be the port the HTTP client will use in the HTTP call when calling our web service).

Line 17: With *ANY the web service is listening on every network device. We can bind the service to a specific network device so that it is only available on a specific network by using the IP address instead of *ANY.

Line 19: In ILEastic HTTP calls are routed to endpoints (in our case the sayHello procedure). With il_addRoute we specify which URL is routed to which procedure(s). We are also limiting the routing to our endpoint for just HTTP GET request (HTTP method GET).

Line 21: So far nothing really has happened/started. We need to call il_listen to actually start the web service and listen for HTTP requests.

Line 26 - 29: This is the procedure interface for our endpoint procedure. ILEastic expects exactly this procedure interface for every endpoint and passes the data structures for request and response to it.

There is no return value in this procedure interface. The data is sent to the HTTP client by using il_responseWrite. Every call to il_responseWrite sends one HTTP chunk to the HTTP client. You can call il_responseWrite as often as you like. The data is sent as chunks and the HTTP client on the other side of the request will put the chunks together.

Line 31: We are setting the “Content-Type” of the response to “text/plain” so the HTTP client knows what the sent data is meant to be, in our case : plain text. There are many different MIME Types (also known as Media Types) which describes different kinds of data. You can also define your own Media Types. That makes sense if you want to differentiate between different data representations (f. e. normal format vs extended format).

Line 32: With il_responseWrite we are actually sending data to the client. Notice that we are sending data in chunks but never say when we are finished with sending data. That is because ILEastic does that for us. After it called our endpoint procedure it sends a “finishing chunk” to the HTTP client.

… and that’s it!