Skip to content

Generated Code Structure

Understanding the code generated by the OpenAPI Client Generator.

Directory Structure

When you generate a client, the following structure is created:

output/
├── README.md                    # Client-specific documentation
├── LICENSE.md                   # License information
└── APLSource/
    ├── Client.aplc              # Main client class
    ├── api/                     # API endpoint implementations
    │   ├── [tag]/               # Subdirectory per OpenAPI tag
    │   │   ├── operation1.apln  # Individual operation namespace
    │   │   ├── operation2.apln
    │   │   └── ...
    │   └── ...
    └── models/                  # Data models
        ├── Model1.aplc          # Generated model classes
        ├── Model2.aplc
        └── ...

Structure Notes

  • API Operations: Each OpenAPI operation generates a separate namespace (.apln) file
  • Tag-Based Organization: Operations are grouped into subdirectories based on OpenAPI tags
  • Model Classes: Each schema in the OpenAPI spec becomes a separate class (.aplc) file
  • HttpCommand: The generator expects HttpCommand to be available in the parent namespace or ⎕SE

Main Client Class

The Client.aplc file contains the main client class that serves as the entry point:

:Class Client
    ⍝ Generated metadata and API information in comments
    ⍝ Base URL and version information

    (⎕ML ⎕IO)1

     rVersion
        ⍝ Return the current version
        :Access public shared
        r'API Name' 'Version' 'Generation Date'
    

    :field public BaseURL
    :field public Cookies
    :field public Headers
    :field public Timeout
    :field public VerifySSL
    :field public FollowRedirects
    :field public shared HttpCommand''
    :field public Initialised0

     (rc msg)Initialise
      ⍝ ←Initialise HttpCommand
      ⍝ Checks parent namespace
    
:EndClass

Key Features

  • Configuration Fields: BaseURL, Headers, Timeout, SSL settings
  • HttpCommand Management: Automatically loads or uses parent's HttpCommand
  • Version Information: Shared function returns API name, version, and generation date
  • Initialization: Call Initialise to set up HttpCommand before using the client

API Operation Namespaces

Each API operation generates an individual namespace containing helper functions:

:Namespace operationName
    ⍝ HTTP_METHOD: /path/to/endpoint
    ⍝ Operation description
    
    ⍝ Parameters:
    ⍝ param1: Type, required/optional, Location

    isValidPathParam{
        ⍝ Validation helper for path parameters
        ⍝ Checks if argument is character vector or scalar number
    }

     rparseArgs args
        ⍝ Parse and validate operation arguments
        ⍝ Constructs HttpCommand arguments
        ⍝ Returns: HttpCommand arguments Namespace with Command, URL, ContentType, etc.
    

     rparseResponse response
        ⍝ HttpCommand returns the response body already JSON-decoded (if applicable)
        ⍝ This function interprets that data per status code and maps it to models or errors
        ⍝ Returns: Parsed data or error information
    
:EndNamespace

Operation Structure

Each operation namespace contains:

  1. Validation Helpers: Functions like isValidPathParam for parameter validation
  2. parseArgs: Constructs the HTTP request from provided arguments
  3. parseResponse: Handles different HTTP status codes and parses responses
  4. Documentation Comments: Operation details, parameters, and return types

Model Classes

Data models are generated from OpenAPI schemas:

:Class ModelName
    ⍝ field1: type, required/optional
    ⍝ field2: type, required/optional
    ⍝ ...

    :field public field1 ⍝ type
    :field public field2 ⍝ type
    :field public field3 ⍝ type

     make1 args
        :Access public
        :Implements constructor
        ⍝ Copy args namespace into instance
        ⎕THIS ⎕NS args
    

     buildFormatNS
        :Access public
        ⍝ Build namespace for serialization
        ⍝ Only includes defined fields
        build()
        :If (isVarDefined 'field1')
            build.field1field1
        :EndIf
        ⍝ ... for each field
    

    isVarDefined{
        ⍝ Check if a field is defined in instance
    }
:EndClass

Model Features

  • Type Annotations: Comments document field types and requirements
  • Namespace Constructor: Accepts a namespace to initialise fields
  • FormatNS Method: Builds namespace for JSON serialization, excluding undefined fields
  • Helper Functions: isVarDefined checks field existence
  • Nested Objects: Reference types point to other model classes

HTTP Communication

The generated code uses HttpCommand for HTTP operations. Operations are called through the client:

  • Client checks parent namespace (##.HttpCommand) for existing HttpCommand
  • Automatically upgrades HttpCommand to latest version
  • HttpCommand handles JSON parsing automatically

Error Handling

The generated client surfaces errors through HTTP status codes and the HttpCommand abstraction. Network-level or protocol issues are exposed via HttpCommand, while application-level errors are represented as non-success HTTP responses that your code is expected to inspect and handle explicitly.

Error Handling Approach

  • Each operation's parseResponse handles expected status codes
  • HttpCommand provides HttpStatus field for checking responses
  • Error responses are returned as-is (pre-parsed by HttpCommand)
  • Client code should check result.statusCode (if using syncDetailed) to determine success/failure

Customization

TODO

Next Steps