An API-first approach is a paradigm shift, or rather, a departure from how we built traditional applications, fundamentally changing the way we architect, design, develop, integrate, and consume many aspects of enterprise application development today. This paradigm shift is important for IBM i shops since it allows them to embrace new technologies such as REST, GraphQL, event-driven programming, etc.
By Joydip Kanjilal
This article will examine modern API strategies for IBM i using REST and GraphQL—we will discuss modern API approaches for IBM i, including REST and GraphQL, while examining how an organization can build APIs in a way that retains the reliability of its existing legacy RPG applications.
What is an API-First Architecture?
API-First is an architectural approach that focuses on implementation and on how services interact, producing systems that are more robust, flexible, and scalable to the increasingly rapid pace of business and technology.
This approach focuses on creating applications by exposing an application's business logic using one or more Application Programming Interfaces (APIs), which are typically created even before the application’s business logic components are built.
API first does not mean that everything should become a microservice. It also does not mean that every RPG program has to have an endpoint. It means API clients consume IBM i through well-defined contracts. API-first approach offers IBM i teams several advantages:
- The API consumers never need to know or access the legacy RPG code; they only need to know how the business logic works.
- Using an API-first approach, you can modernize your RPG programs using the latest tools, technologies, and architectural concepts and guidelines without forcing all API clients to change.
- In a typical API-first approach, the teams test the contracts before they actually implement them in the code
API-first does not mean every application needs to be a microservice — you have access (and should leverage) the data you must integrate. Nor does that mean an endpoint is necessary for every RPG program — the API should reflect business capabilities; it should never reveal the business logic underneath.
Why an API-first Architecture Matters
Here's why API-first architecture matters:
Increased agility and rapid application development
An API-first approach enables parallel development—Different teams, e.g., front-end, Back-end, mobile development, third-party integration, etc., can work on different parts of the application at the same time without waiting for others to complete their builds. For instance, the front-end dev team can develop UI against mock APIs, and the back-end team can implement business logic and expose it using APIs. Well-defined API contracts reduce assumptions and miscommunication amongst the development teams, minimizing integration problems and expediting debugging.
Enhanced Collaboration and Communication
APIs are agnostic contracts that dictate how programs or software services communicate with each other, no matter the technology also in use. Therefore, having a clear, unambiguous communication artifact increases collaboration in large organizations and with peers outside the organization. Clear APIs will ensure the whole team, from product managers to developers, understands both what this system can do and how it transfers data.
Better Developer Experience
Developers who consume an API know exactly what to expect regarding request and response data, formats, and error handling, thereby reducing the time to integrate the user interface components with the APIs. An API-first approach generally involves creating and documenting APIs that do not depend on the application's main logic. Because an API-first approach uses extensive, continually updated API documentation, this helps developers, especially those being onboarded, understand how the APIs work.
Consistency and Standardization
Using an API-first strategy, organizations can use consistent terminology, data structures, security mechanisms, and error handling mechanisms across their APIs. This standardization helps maintain APIs and enforce consistent rules, protocols, and design practices across them.
Greater Reusability, Flexibility, Decoupling
Legacy RPG applications have been in operation for decades, automating transaction processing (order, payment, inventory, etc.). The code contained in these legacy applications is also a valuable source of tested business expertise.
Modernizing these applications can be risky, time-consuming, and costly; the risk of rewriting all of the code can lead to significant business impacts. Therefore, the most logical solution is to create a wrapper around your legacy RPG code, using modern technologies.
The wrapper will provide access to business logic currently embedded within the legacy RPG applications through APIs. In essence, you will retain the benefits of both the legacy code (i.e., what is currently working) and modern service creation approaches (i.e., APIs).
Implementing loosely coupled services through an API-first architecture offers many advantages. For instance, if you make changes to the API contracts related to a service, implementing an API versioning technique ensures these changes won’t affect any other services.
Thus, changing the API contract will not cause the failure of services that are already in operation. Therefore, loosely coupled services add resiliency to the entire system. Multiple clients may use one API: for example, these may be mobile or web applications, IoT partner integrations, and more.
This way, you can build different components of a system using different technologies and programming languages, enabling each project team to use the best tool for their specific project while still having interoperability.
Future-Proofing and Scalability
API-first architecture enables greater flexibility for integrating new clients as they become available, or removing/adding services as your business needs change or new technology becomes available. Services that are decoupled from each other can scale independently based on the resource utilization associated with high-demand areas of your systems.
Ecosystem Development and Monetization
As is true for many enterprise applications, for many businesses, APIs represent more than simply an Internal integration point; they are themselves a product. The foundation of an API-first strategy is to provide an easy way to expose high-value data or functionality through APIs, which can lead to the development of third-party solutions and ultimately the generation of revenue from new sales additions to your ecosystem.
None of these protocols specify the structure of business logic; they merely specify how consumers access it. This distinction becomes especially important in the next question: where does RPG fit in this picture?
Where RPG belongs
You may often have an RPG program that calculates prices, applies credit rules, allocates stocks, and commits an order. Because your legacy RPG application is stable, you should leave the business logic there and avoid replicating this logic in your API layer. Instead, you should follow these strategies to maximize the benefits of this blend of your API and RPG layers.
- Use a service procedure or wrapper program that accepts a clear command.
- Your RPG layer should contain the necessary business logic, i.e., it should perform validation, business processing, and manage transactions.
- Based on the outcome of execution of the transaction, the RPG layer should return the result, request, status, and, if the transaction processing failed, structured errors.
Versioning
Contrary to your legacy RPG programs, APIs need to evolve constantly. You can have API endpoints that are deprecated, API methods that have newer signatures, changes to response formats, etc.
When designing APIs, versioning is essential because you often have to make changes to your API to cater to client requests, and there should be a way to help ensure stability and reliability and identify the newer versions of those APIs. API versioning is a technique used to cater to these changes—it enables your APIs to evolve by ensuring that existing APIs don't break even if changes are made to certain endpoints.
API versioning is useful to keep your API backward compatible when you make changes to it gradually. With versioning, you can dictate which clients get to use that feature and keep older clients working with your API while new features or breaking changes are added.
Another advantage of API Versioning is that you will not have to force your application users into an upgrade to a newer version. API Versioning plays an important part in avoiding compatibility issues arising from multiple API versions being used, helping us achieve Quality and reliability in the code plan and bringing changes with good practice.
API versioning also allows you to add new features or make changes to the API without impacting all your users at the same time. Your new API version can be rolled out to a small number of users for feedback and then pushed more widely upon success. This enables you to make faster changes to your API while still keeping a stable and reliable system for most of the users.
API versioning is useful to keep your API backward compatible when you make changes to it gradually. With versioning, you can dictate which clients get to use that feature and keep older clients working with your API while new features or breaking changes are added.
Another advantage of API Versioning is that you will not have to force your application users into an upgrade to a newer version. API Versioning plays an important part in avoiding compatibility issues arising from multiple API versions being used, helping us achieve Quality and reliability in the code plan and bringing changes with good practice.
API versioning also allows you to add new features or make changes to the API without impacting all your users at the same time. Your new API version can be rolled out to a small number of users for feedback and then pushed more widely upon success. This enables you to make faster changes to your API while still keeping a stable and reliable system for most of the users.
The code below applies the required settings to configure API Versioning.
builder. Services. AddApiVersioning(options =>
{
options. DefaultApiVersion = new ApiVersion(1, 0);
options. AssumeDefaultVersionWhenUnspecified = true;
options. ReportApiVersions = true;
options. ApiVersionReader = ApiVersionReader. Combine(
new UrlSegmentApiVersionReader(),
new HeaderApiVersionReader("X-Api-Version"));
});
Below is the required API code to apply the versioning:
[ApiController]
[Route("api/v{version:apiVersion}/orders")]
[ApiVersion("1.0")]
[ApiVersion("2.0")]
public class OrdersController : ControllerBase
{
[HttpGet("{id}")]
[MapToApiVersion("1.0")]
public IActionResult GetV1(int id) =>
Ok( new { Id = id, Status="Shipped"} );
[HttpGet("{id}")]
[MapToApiVersion("2.0")]
public IActionResult GetV2(int id) =>
Ok(new {Id = id, Status = "Shipped"});
}
Last but not least, this is how you can invoke APIs from an API consumer or client:
GET /api/v1/orders/123
GET /api/v2/orders/123
GET /api/orders/123
API Lifecycle Management and Governance
Versioning alone is not governance - an IBM i shop accumulates APIs across order management, i.e., creating and updating orders, inventory updates, and customer service interactions.
The best place to start is documenting your contracts with OpenAPI. An OpenAPI specification covers every endpoint, request, and response schema as well as the error format in a machine-readable fashion that enables IBM i teams to automatically generate client SDKs from it and validate requests at the API gateway without manual intervention through contract testing.
Contract governance also enforces who can introduce a breaking change and how. A simple but effective policy here would require an architectural review before any breaking change ships, publish a fixed deprecation window for the old versions, and ensure the new major version runs in parallel with previous versions until consumers migrate to the newer version.
REST vs GraphQL vs gRPC
REST (Representational State Transfer is an architectural style with HTTP as a transfer protocol invented by Roy Fielding in 2000. You probably have heard of REST; it is an industry standard that every developer in the world will propose whenever you want to build an API– and it's been around for a long time. Still, it has its limits when implementing this kind of communication.
GraphQL can eliminate many of the limitations associated with REST. Using GraphQL, you can create a single endpoint to query your data for one specific use case. Imagine if we were able to combine this knowledge into the data with one query from our client using GraphQL.
For instance, the customer would get all their order history, credit score, and stock data in a single request. With a GraphQL client, the client builds and defines a clear query specifying what data it needs from the server, and only that data is returned by the server.
gRPC overview: A high-performance, open-source universal RPC framework that runs over HTTP/2 and uses Google's Protobuf technology to stream data during service-to-service communication. REST is great for public APIs; GraphQL is good if you are looking to pull lots of data (maybe from different aggregate sources); and gRPC is good where speed matters in internal microservice communications.
Here are the recommendations on whether or not IBM i organizations should go for REST or some other technology: REST is a good default choice in most cases for IBM i companies; people from RPG and middleware teams know it well, it is useful in an API gateway context, and its integration is something that everyone who works with an external partner or a mobile application expects. GraphQL can be used selectively when one particular consumer, be it a customer portal or some mobile application, requires data to be gathered from multiple IBM i data sources or RPG programs at once and the team is prepared to build and support a GraphQL schema layer; it means that using GraphQL as a substitute for REST on a large scale is not a viable option. gRPC is by far the least used of these three technologies in the context of IBM i: mainly because it is suitable for sending messages between machines (service-to-service communication). Still, it is mostly needed when your organization is building a more complex microservices application in .NET or Java.
API Gateways
An API Gateway accepts requests from API consumers or clients, forwards them to your backend services, and returns the corresponding responses. Instead of each API client having to call the downstream services, the gateway routes requests to them. The API Gateway handles routing, authentication, rate limiting, caching, and logging. By using an API Gateway, you can build an architecture that centrally manages cross-cutting concerns. Figure 1 below illustrates a typical API Gateway.
Figure 1: A typical API Gateway
The key responsibilities of an API Gateway include the following:
- Routing: This is a feature that can forward requests to the respective downstream services, which can also include IBM i-hosted endpoints.
- Security: You can use API Gateways to authorize API keys, validate JWT tokens, and enforce TLS
- Rate limiting and throttling: You can take advantage of rate limiting and throttling to protect backends from overflowing requests
- Aggregation: This is a feature that aggregates multiple responses from multiple services
- Observability: This is a feature that unifies metrics, traces, and logs, enabling you to view them in a centralized place
A Practical IBM i Architecture
In a typical IBM i architecture that uses an API Gateway, you can clearly separate core business logic from the client communicating with it. The API Gateway can be placed in front of the IBM i application, exposing the business logic residing in legacy RPG programs through REST APIs consumable by web, desktop, and mobile applications.
The client sends a request to the API gateway, which authenticates the caller, applies rate limits, and forwards the call to the backend system. On the IBM i side, that backend is typically one of a few integration methods; each suited for different types of scenarios:
IBM i Web Services (IWS): When your primary need is to rapidly expose existing RPG or COBOL programs and service programs as SOAP or REST web services with little custom middleware code, ideally if the consumers can consume IWS-generated WSDL or REST contracts out-of-the-box.
Db2 for i REST Services: This is a good choice if the integration need is more data-focused, no existing RPG business logic needs to be invoked because all that must happen is querying or updating of Db2 for i tables and views via SQL; fast to set up mainly for simple read-heavy CRUD scenarios mean that this service can get you up and running quickly at low complexity; however should NOT be used as a mechanism in which an application escapes from using an RPG program which performs important business rules on the same data.
Integration adapters and middleware: This includes integration adapters, RPG over NET or Java-based connectors invoking RPG through ODBC, JDBC or program-call APIs. Good for cases when out-of-the-box IWS and Db2 for i REST Services don't have sufficient request transformation, orchestration across multiple RPG calls, or business-rule-aware error handling as needed.
Figure 2: A Practical IBM i Architecture
Now, consider that a client sends the following request:
POST /v1/orders
Authorization: Bearer <specify your access-token here>
Content-Type: application/json
{
"customerId": "C001",
"currency": "USD",
"lines": [
{
"sku": "P-1008",
"quantity": 50
}
]
}
Here is the sequence of steps in this workflow:
- The client sends a request with an authorization token in the request header
- The API Gateway receives the request
- Next, the API Gateway authenticates the request and checks if the client is authorized to call the requested service.
- The API Gateway then checks if the client has exceeded its quota of allowed requests for a specific duration (e.g., 100 requests/minute).
- If the client has exceeded its quota, the API Gateway returns HTTP 429 (Too Many Requests).
- The API Gateway checks the token or API key. If the token or the key is invalid or expired, it returns HTTP 401 (Unauthorized), and the request never reaches the backend services.
- The API Gateway analyzes the routing rule and routes the request to the respective downstream service or an integration adapter calling an RPG program.
- The backend service returns the result to the API Gateway.
- The API Gateway logs, metrics, and traces at every step of the process.
Here is how a successful response should look:
HTTP/1.1 201 Created
Location: /v1/orders/SO-784231
{
"orderId": "001",
"status": "accepted",
"total": {
"amount": 350.00,
"currency": "USD"
}
}
Security Considerations
Implementing authentication at the API Gateway level is the first step, but that is not the only one. Organizations that expose RPG business logic through APIs should also consider each of the following points:
Enforce Authorization: Authentication is knowing who the caller is, whereas authorization knows what that caller can do. Use fine-grained authorization at the API layer, so a customer reading order status cannot cancel orders or read data for another customer.
Use Audits: You should record every API interaction with business-critical IBM i data, including a subject identifier for the caller and when they made their request; also track the outcome of calls — success or failure; ideally this should line up to journal entries in underlying files, making it clear what file changed at what time. This provides an end-to-end audit trail from the external API call to the one Row in Db2 for i that changed due to compliance and dispute resolution.
Use IBM i object security: The API and gateway layers do not supplant IBM i's own OLS (object-level security). IBM i native object authorities, adopted profiles, or utility authorization lists persist in authority enforcement on underlying files, programs, and libraries, so a compromised API credential cannot access more than the service account's IBM i profile is authorized to access. Ensure the service account that your API layer uses to call RPG programs is applied with least privilege.
Implement TLS best practices: You should ensure that all traffic between clients, the API gateway, and IBM i-facing services uses an allowed set of ciphers that enforce strong protocols, continuously monitor and measure whether those requirements are being met by turning off older cipher suites promptly plus rotate certificates on a schedule established for each certificate using standard methods or techniques.
Common Mistakes
Here are some common mistakes that IBM i teams make when adopting APIs:
- Overengineering your API endpoints: You should not wrap each RPG program with APIs. You need APIs based on your business requirements. Creating APIs for just about every RPG program creates a brittle API based on internal structure rather than the business needs.
- Duplicating business logic: An API, or a piece of middleware, isn't meant to re-implement the rules in C#/NET but enforce those when being called through RPG. What you are doing here is creating a dual stream of information that will and can eventually conflict with one another.
- Avoid Weak Authentication: You should use authentication at the gateway level to prevent unauthorized and invalid requests from ever reaching your backend services.
- No Versioning: Most organizations release a specific version of an API without adding versioning to the URL, making it impossible to deploy changes.
- Rate Limiting: Implement rate limiting so that you do not overwhelm your downstream services, i.e., limit traffic before it hits RPG.
- Correlation IDs and Observability: You can't know what went wrong in the system without having a correlation ID.
Takeaways
- API gateways provide API consumers a unified access point to the downstream services in an application.
- Your legacy RPG programs should be at the domain core. You should never duplicate business logic already written in your legacy code in the API layer.
- You should use your API as a wrapper for your RPG code, exposing the essentials while encapsulating the business logic from the outside world.
- The API Gateway should implement authentication, rate limits, routing, etc and allow only valid requests to reach the downstream RPG services.
- You can use a Correlation ID to trace the entire request path, from when the client calls your API Gateway service to the downstream or backend services.
API-first modernization on IBM i isn't only about replacing RPG, but about extending the value that already exists in the business logic built into it. The legacy RPG programs have been created over the last decades and contain thousands of hours of working code that show how the business really works. When that logic is encapsulated using secure APIs, organizations can succeed in this paradigm shift toward modern technologies while allowing proven, tested, working RPG code to do what it does best.
Business users want new applications now. Market and regulatory pressures require faster application updates and delivery into production. Your IBM i developers may be approaching retirement, and you see no sure way to fill their positions with experienced developers. In addition, you may be caught between maintaining your existing applications and the uncertainty of moving to something new.
IT managers hoping to find new IBM i talent are discovering that the pool of experienced RPG programmers and operators or administrators with intimate knowledge of the operating system and the applications that run on it is small. This begs the question: How will you manage the platform that supports such a big part of your business? This guide offers strategies and software suggestions to help you plan IT staffing and resources and smooth the transition after your AS/400 talent retires. Read on to learn:
LATEST COMMENTS
MC Press Online