An IBM-i Service Program is a collection of reusable procedures and data items that can be accessed by other Integrated Language Environment (ILE) programs or service programs on the IBM i (AS400/iSERIES) system.
Here are some key points about service programs:
We reference the Service Program Procedures in the calling program. The service program is created and is loaded into memory when the calling program uses one of the service program procedures.
For example, imagine a service program had these procedures in it:
DCL-PROC AddNumbers;
DCL-PI *N INT(10);
NUM1 INT(10);
NUM2 INT(10);
END-PI;
RETURN NUM1 + NUM2;
END-PROC;
// SubtractNumbers - receives two numbers, subtracts num2 from num1 and returns the results
DCL-PROC SubtractNumbers;
DCL-PI *N INT(10);
NUM1 INT(10);
NUM2 INT(10);
END-PI;
RETURN NUM1 - NUM2;
END-PROC;
In this example, AddNumbers and SubtractNumbers are procedures stored in an RPG module. The module is compiled into a service program, which acts like a toolbox of reusable business logic. After creating the service program with CRTSRVPGM, it is added to a binding directory using ADDBNDDIRE. Think of the binding directory as a contact list for service programs. When another program is compiled, the compiler checks the binding directory to find the procedures it needs. This means your programs can call AddNumbers and SubtractNumbers without worrying about where the actual code lives, making your applications more modular and much easier to maintain.
How is the Service Program referenced by normal programs?
A regular program would need to be told that it is using a service program by adding either a binding directory (BNDDIR) or a specific service program name (BNDSRVPGM) to its control specifications. This tells the compiler and binder where to find the external procedures referenced in the source code. During compilation, the binder resolves procedure calls such as AddNumbers and SubtractNumbers by locating them in the service program. Most developers prefer using a binding directory because it acts as an abstraction layer between the program and the service program objects. Instead of hard-coding service program names into every program, the binding directory maintains a list of available service programs. If a service program is replaced or additional service programs are added, programs can often be recompiled without source changes. This makes your applications more modular, easier to maintain, and far less likely to cause headaches during future upgrades.
For example, the program might specify a binding directory in its control options:
or directly reference a service program:
Using a binding directory is generally the preferred approach because it decouples the calling program from the underlying service program implementation. Think of it as using a contact list instead of memorising everyone's phone number. The program knows who it wants to call, and the binding directory knows where to find them.
You might use the sub-procedures, sucked in from that service program, like this:
eval fatnumber = 256;
eval tinynumber = 37;
eval result = SubtractNumbers (fatnumber:tinynumber);
// value 'result' now contains '219'
We would create this using the CRTSRVPGM command:
CRTSRVPGM SRVPGM(MYLIB/MYSRVPGM) MODULE(MYLIB/MYMODULE) EXPORT(*ALL)
The 'CRTSRVPGM' command creates the service program and specifies that all procedures in the module should be exported.
