Blog

This blog is usually for boring…technical detail. For more interesting post, go checkout my linkedIn post!

What is OpenAPI-generator? It’s basically a program that allow you to generate boiler plate api code in your choice of programming language (ts, java, python, Go, etc..) based on openapi spec file given.

Before contributing to OpenAPI-generator. I wanted to have basic level of understanding about their codebase first before anything. The following contains the rough note about my finding.

First Glance

When openapi spec file is given, this is rougly a flow of how it generates api’s.

  • Spec file (yaml/json) -> Parser (Swagger Parser)
  • Parser -> Normalizer
  • Normalizer -> DefaultGen
  • DefaultGen –> CodegenConfig[CodegenConfig / DefaultCodegen.java]
  • CodegenConfig –> LanguageCodegen[TypeScriptClientCodegen.java]
  • LanguageCodegen –> TemplateManager[TemplateManager & Mustache Engine]
  • TemplateManager –> GeneratedFiles[TypeScript / Java / Go / etc. Output Files]

Normalizer

  • Implemented in OpenAPINormalizer.java, this component pre-processes the in-memory OpenAPI object model before code generation starts.
  • Simplify redundant code (allOf, anyOf, oneOf). For example
components:
schemas:
DeliveryStatus:
type: object
properties:
status:
oneOf:
- type: string
enum: [PENDING, PROCESSING]
- type: string
enum: [SHIPPED, DELIVERED]
- type: string
enum: [CANCELLED]

into

components:
schemas:
DeliveryStatus:
type: object
properties:
status:
type: string
enum:
- PENDING
- PROCESSING
- SHIPPED
- DELIVERED
- CANCELLED
  • Filter specific endpoint (FILTER); instead of ingesting all of the spec file, filter specific part of a spec file user cares about
  • Clean up inline code definition; if user declared object inside the array or object instead of using component, normalizer create named component and use it as ref.
  • For Example, if we have this
For Example, if we have this
components:
schemas:
User:
type: object
properties:
id:
type: integer
name:
type: string
address:
type: object # <--- This is defined inline
properties:
street:
type: string
city:
type: string
zipcode:
type: string

it turns into this

components:
schemas:
User:
type: object
properties:
id:
type: integer
name:
type: string
address:
$ref: '#/components/schemas/User_address' # <--- Clean reference
# The normalizer automatically created this named component!
User_address:
type: object
properties:
street:
type: string
city:
type: string
zipcode:
type: string

Default Gen (DefaultGenerator.java)

  • Located in DefaultGenerator.java , this class is the core orchestrator/engine of the entire application.
  • convert OpenAPI object into something generator framework can understand
  • It traverses the OpenAPI object graph and translates OpenAPI definitions into standard, language-agnostic Java models (CodegenModel, CodegenProperty, CodegenOperation, CodegenParameter, CodegenResponse, etc.).

LanguageCodegen

  • applies language specific customization; eg: naming convention, mapping types to language primitive, identify which import statements and dependency needed
  • escape specific reserve keyword like interfacetypeany and rename them into something similar like _type (depends on configs)

TemplateManager & Mustache Engine

  • TemplateManager.java handles file I/O and interfaces with the template engine (typically JMustache, or alternatively Handlebars).
  • it parse target mustache template
  • render variable

Posted in

Leave a comment