- Separate your application into different layers
- Use Bootstrap for your HTML/CSS within web apps.
- Use Ionic for your HTML/CSS within mobile apps.
- Use AngularJS for your presentation logic and to consume the web API.
- Use PHP, CL, RPG, and DB2 to build your web API.
There is an almost countless number of technologies available for application development on IBM i. It can be difficult to figure out which tools to use and what roles they should play in your application. What I’ll offer here is an opinionated technology stack for structuring your web and mobile applications. This model applies to individuals or teams that have both PHP and RPG skill sets, and every tool that’s included is free if you already have a Power Systems server running IBM i.
The value of separation of concerns is simplifying development and maintenance of computer programs. When concerns are well-separated, individual sections can be reused, as well as developed and updated independently. Of special value is the ability to later improve or modify one section of code without having to know the details of other sections, and without having to make corresponding changes to those sections.
Basically I’m referring to the subject of multi-layered architecture. Separate your software into layers (with each layer having its own responsibility) and you have more maintainable and reusable code. There’s a general consensus within the development community that multi-layered architecture is overkill for really small projects. This makes sense to me. However, if you can afford it then you should try multi-layered architecture on a small project. This will enable you to become familiar with the approach on a small scale, serving to get your feet wet so that you can be prepared to tackle larger applications in the future.
The Back End
The back end should contain all of your business/domain logic as well as the database/persistence layer. It should take the form of a RESTful Web API. That is, your server-side code should be made accessible through a well-defined set of HTTP requests that follow the REST pattern. The Apigility documentation contains an excellent description and comparison of the two major types of APIs. It concludes that in most cases REST is a better format than RPC. Thus in the stack I’m advocating you should build a web API comprised of RESTful web services that returns JSON strings.
PHP was built for the web. Consequently it’s adept at handling web-related tasks and thus a good candidate for handling HTTP requests and responses. PHP is also a full object-oriented language that can be used to build the entire domain layer of your back end, but since we’re assuming that your development team also has RPG skills we’ll pass that responsibility to the RPG developers. So PHP will be the application layer of your API, which is layer between the HTTP requests/responses and your business logic.
Apigility provides developers with a web administration UI for designing our APIs. Thus it automates the tasks of interpreting HTTP requests, filtering and validating the data, handling errors, and formatting output. It handles the creation of PHP files for you. However, once the files have been generated and initialized you will need to do a small amount of manual coding.
PHP Toolkit for IBM i
Once PHP has filtered and validated the data it can then pass that data to RPG and CL via the PHP Toolkit for IBM i. The toolkit, maintained by Zend, is an open-source set of PHP classes that interacts with the XMLSERVICE library to grant PHP access to system resources. You will have a method in your *Resource PHP class that passes each value to the CL program via the toolkit object’s AddParam*() methods. This method will take the return values from CL and generate the proper response. There are many ways to handle it, but returning a PHP array from this method will send that array formatted as a JSON string as the HTTP response. If some kind of error has occurred then you will return an ApiProblem object passing it an HTTP status code and an error message.
Control Language (CL) allows us to execute a set of IBM i commands as a program. In this stack it’s useful as a wrapper for your RPG programs. If an RPG program doesn’t complete then it won’t return control to its calling program. It’s usually waiting on a reply to an error message. This can be problematic when the program is called from an HTTP request because we want to ensure that the request doesn’t timeout. So for this stack CL will simply receive the data from PHP and pass it to RPG while monitoring for messages.
As you probably already know RPG is a language written to run on IBM i. It is a high-level programming language that was written for business/enterprise systems. Thus it’s an ideal candidate for the business/domain logic layer of your applications. Gone are the days of SDA and printer files. In this stack it receives data from the CL program, executes the business logic and interacts with the persistence layer (database) via SQL. Then it returns data to the calling CL program.
DB2 is a relational database management system with excellent performance and many advanced features. In this stack we use it as a persistence layer. All of the data is stored in SQL tables (though you could just as easily use DDS physical files) and accessed via SQL statements. Presumably the database design would include multiple indexes and views for performance and data integrity reasons.
The Front End
Encapsulating the different application layers results in a more modular approach to programming. Using interchangeable parts means that a change to one part doesn’t lead to unintended consequences in other parts of the application. I know it sounds like a lot of tools to learn, but you don’t have to learn them all right now. That’s part of the beauty of multilayered architecture. Encapsulation can be incremental. Your application can become increasingly modular as you gain the necessary knowledge and refactor it.