The Developer Experience

A guided tour from the developer's perspective

The Structure of Your New Solution

A simplified diagram of your new system's architecture

This section describes our solution's structure in a little more detail. It's geared toward the more technical reader like a Devops professional. The diagram shows a simplified version of your new solution architecture. It's a very common modern architectural pattern that uses a client SPA to communicate with backend web APIs. We'll break these components down a little bit in the following discussion. We'll also show several examples of digital asset transformation including the old asset format, the new version, and in some cases a little descriptive detail.

The Structure of the SPA

A simplified diagram of the SPA's architecture

Your SPA is the part of the system that the end-user sees, but it also manages all of the communications between that end-users browser and the backend APIs. Important parts of security, user data management, work state, and data connection management are handled by the SPA.

A simplified structural diagram of the SPA is included here. It shows that the SPA is a combination of Twin Oak components and components that you may add to the system. The Twin Oak React components library form the basis of most of the visual and non-visual behaviors of the SPA, including the core functionality of request message transmission and response message dispatching. Most this messaging is done to exchange data with the backend web APIs.

Many of the Twin Oak components load JSON data from backend web APIs to drive their appearance and behavior. These components include: a dynamic menu component, form layout component, DFU component, and the file viewer component. These components rely on a framework of supporting components for things caching, security, and messaging. The supporting components are designed to improve the ease of creation and consistency of operation amongst all client components in the SPA.

Customers can extend the SPA by adding their own components to it. Customer components can and should leverage the supporting components whenever possible. However, if necessary, a developer can choose to bypass the supporting components and interact directly to other backend systems in your environment.

The Structure of the Host

Our host is built by combining your translated code with the Twin Oak platform. This platform consists of our Web APIs, our runtime engine, our procedural state machine, our data adapter layer, and our workflow subsystem. Our cloud-hosted Web APIs provide the backbone of our solution. Our endpoints allow for:

  • The invocation of programs, procedures, and other applications
  • Access to configuration data like menus, user info, forms, etc.
  • Storing and/or accessing data files and generated reports
  • Reading and/or writing workflow data
  • Other system information

Many of these items are created by translating your existing code, configuration, or data files. They are maintained in the cloud going forward.

Our procedural state machine allows the SPA to invoke your translated procedures and therefore your programs. This state machine is needed in order to reconcile the differing user interaction models that are used in AS400 procedures versus a web browser and server. If a procedure requires user interaction then it needs to be broken into steps for execution that supports the web model. This reorganization is done automatically by our translators and the invocation of these steps is orchestrated transparently by the SPA to run your programs.

Our runtime engine is used by translated RPG programs to emulate the standard RPG program logic cycle (PLC). This engine provides data to and controls the execution of your programs - just like the standard RPG PLC does, including detail and total calculations, indicator management, the LDA, record types and control levels. The primary difference is that our engine runs in the cloud to host your programs within our framework. Otherwise your programs run as they did before.

Our data adapter layer handles the data storage and retrieval of your translated data files. It also provides several features of the indexing and cataloging elements of the AS400 designed to improve performance over basic file reads and writes. We expect this layer will be expanded soon to support direct LINQ access to your data from C#.

Our Business Workflow Tracking sub-system allows users to manage the progress of tasks that comprise your business's workflow. You can use this system to schedule, initiate, assign, and complete tasks using a set of customizable workflow templates. You can also monitor the status and progress of those tasks and even add notes or attach files to each of the steps.

Our tour of the developer experience focuses on the transformation of the source and/or configuration files in the translated system. This set of things includes all of the items from the user experience (menus, screens, DFUs, and report outputs) plus the procedures, programs, and data files.

The Transformation of Your Digital Assets

All of the digital assets in your current system are transformed during our migration process. This section offers a quick overview of these transformations, showing that the content — and business value — of each asset is retained but the format has changed to improve compatibility with more modern techniques.


Our menu translation converts your AS400 menu definitions into JSON documents that describe those same menus. The JSON documents are used as configuration inputs to the SPA which loads them at launch in order to render those menus. The menus are rendered using a custom React menu component from the Twin Oak libraries.

Click here to see the live, translated version of this menu.

An excerpt of the original menu source. Click here to download the original source text.

An excerpt of the translated menu source. Click here to download the generated JSON file.


Our screen translation converts the AS400 screen definitions to JSON files. These JSON files are fetched from an API endpoint and rendered by a custom client component in the SPA. The forms retain their original labels and field entry areas, with the same ordering, layout, and data types as the originals.

An excerpt of the original screen source. Click here to download the original source text.

An excerpt of the translated screen source. Click here to download the generated JSON file.


Our Data File Update (DFU) translation converts your AS400 file record definitions to DFU-centric JSON files. The DFU Editor uses these JSON files to drive its editing and rendering process via a custom client component in the SPA. Since this JSON is stored on the server, the DFU editor component retrieves the proper file from a server web API before opening your data file for editing. We initially include ALL of the fields and ALL recordtypes in the your data file uses in the JSON definitions, but you can modify them to hide fields or recordtypes, change field labels, or rearrange fields if you want to. The DFU Editor component supports all of the same field data types used in the legacy system including packed fields.

Click here to see the live, translated version of this DFU.

An excerpt of the original DFU source. Click here to download the original source text.

An excerpt of the translated DFU source. Click here to download the complete generated JSON file.


Our procedure translator converts (most of) your JCL to C# code that runs on the cloud host. Because JCL sometimes solicits user inputs and then continues to run, these procedures need to maintain some program state before and after user interactions. This is a little different from the web interaction model, so in order to support these types of user queries and the necessary state management, our translated code actually generates a state machine definition for each procedure. The SPA has been designed to interact with the web api backend and drive this state machine through its steps in the proper order, collecting user input where required and then sending those inputs back to the state machine cloud host where they can be processed. Other than seeing your procedure partitioned into several steps, this process is mostly transparent.

An excerpt of the original procedure source. Click here to download the procedure text.

An excerpt of the translated procedure source. Click here to download the generated C# file.


Our RPG program translator converts your RPG to C# code that runs on the cloud host. The generated code depends upon several support libraries and objects and attempts to maintain the familiar appearance of your original code while still being modern C#. All of the RPG opcodes have been implemented as methods in our custom runtime library to enhance the readability for RPG programmers and to encapsulate the idiosynchrasies of RPG.

Translation maintains your file names, field names and subprogram names unless they contain characters that are illegal in C#. The translator also collects the total calculations and detail calculations into handler procedures with appropriate names and similarly organizes the total, detail, and exception output statements into groups. Reproducing the RPG output behaviors requires a few additional methods. Structured programming elements translate almost identically between the two languages; indicator-based conditional execution is translated into C# if-then statements, while coalescing adjacent matching conditionals into a single if-then group.

The excecution model for the translated code is straightforward. Each program is generated as a C# class, implemented as several partial class files. The class initializer sets up the file fields and record definitions and then invokes a PLC-like engine that drives the processing of file records, invoking the calculation and output methods as appropriate.

An excerpt of the original RPG program source. Click here to download the complete RPG program text.

An excerpt of the translated C# program source. Click here to download the complete generated C# program source as a .zip file.

Data Files

Our data file translation converts your existing data files into a format that is more compatible with our generated code. We convert the data for all RPG field types, including packed fields. In the cloud solution, these data files are stored in Azure file storage; for non-cloud hosting, they are stored in the local file system. This convention helps with code compatibility and gives good data access speeds.

An excerpt of the original data source. Click here to download the complete file contents.

An excerpt of the translated input data file as seen our file explorer tool. Click here to download the complete translated file.