Skip to content
Jack Evans edited this page Jun 7, 2026 · 5 revisions

Examples

These examples are generated from the OpenAPI documents in testdata/examples. Each schema block is the components.schemas fragment from the source document, followed by the Elm modules generated for that example.

Enum

String enums generate custom Elm union types plus decoders and encoders.

BookStatus:
  type: string
  enum:
    - draft
    - published
    - archived

Generated/BookStatus.elm

-- Generated by elm-openapi-codegen. Do not edit.
module Generated.BookStatus exposing (BookStatus(..), bookStatusDecoder, bookStatusEncoder)

import Json.Decode as Decode exposing (Decoder)
import Json.Encode as Encode


type BookStatus
    = Draft
    | Published
    | Archived


bookStatusDecoder : Decoder BookStatus
bookStatusDecoder =
    Decode.oneOf
        [ Decode.map (always Draft) (exactString "draft")
        , Decode.map (always Published) (exactString "published")
        , Decode.map (always Archived) (exactString "archived")
        ]


bookStatusEncoder : BookStatus -> Encode.Value
bookStatusEncoder value =
    case value of
        Draft ->
            Encode.string "draft"

        Published ->
            Encode.string "published"

        Archived ->
            Encode.string "archived"


exactString : String -> Decoder String
exactString expected =
    Decode.string
        |> Decode.andThen
            (\actual ->
                if actual == expected then
                    Decode.succeed actual

                else
                    Decode.fail "Unexpected value"
            )

Default Values

Supported default values are used as decoder fallbacks instead of wrapping the field in Maybe.

InventoryItem:
  type: object
  properties:
    stock:
      type: integer
      default: 0

Generated/InventoryItem.elm

-- Generated by elm-openapi-codegen. Do not edit.
module Generated.InventoryItem exposing (InventoryItem, inventoryItemDecoder)

import Json.Decode as Decode exposing (Decoder)
import Json.Decode.Pipeline exposing (optional)


type alias InventoryItem =
    { stock : Int
    }


inventoryItemDecoder : Decoder InventoryItem
inventoryItemDecoder =
    Decode.succeed InventoryItem
        |> optional "stock" Decode.int 0

anyOf and Discriminator

Union schemas generate Elm union types. Discriminators decode by tag when a mapping is provided.

Animal:
  anyOf:
    - $ref: '#/components/schemas/Cat'
    - $ref: '#/components/schemas/Dog'
Pet:
  oneOf:
    - $ref: '#/components/schemas/Cat'
    - $ref: '#/components/schemas/Dog'
  discriminator:
    propertyName: petType
    mapping:
      cat: '#/components/schemas/Cat'
      dog: '#/components/schemas/Dog'
Cat:
  type: object
  required:
    - name
    - petType
  properties:
    livesLeft:
      type: integer
    name:
      type: string
    petType:
      type: string
      enum:
        - cat
Dog:
  type: object
  required:
    - barkVolume
    - name
    - petType
  properties:
    barkVolume:
      type: integer
    name:
      type: string
    petType:
      type: string
      enum:
        - dog

Generated/Animal.elm

-- Generated by elm-openapi-codegen. Do not edit.
module Generated.Animal exposing (Animal(..), animalDecoder)

import Generated.Cat exposing (Cat, catDecoder)
import Generated.Dog exposing (Dog, dogDecoder)
import Json.Decode as Decode exposing (Decoder)


type Animal
    = AnimalCat Cat
    | AnimalDog Dog


animalDecoder : Decoder Animal
animalDecoder =
    Decode.oneOf
        [ Decode.map AnimalCat catDecoder
        , Decode.map AnimalDog dogDecoder
        ]

Generated/Cat.elm

-- Generated by elm-openapi-codegen. Do not edit.
module Generated.Cat exposing (Cat, catDecoder)

import Json.Decode as Decode exposing (Decoder)
import Json.Decode.Pipeline exposing (optional, required)


type alias Cat =
    { livesLeft : Maybe Int
    , name : String
    , petType : String
    }


catDecoder : Decoder Cat
catDecoder =
    Decode.succeed Cat
        |> optional "livesLeft" (Decode.map Just Decode.int) Nothing
        |> required "name" Decode.string
        |> required "petType" (exactString "cat")


exactString : String -> Decoder String
exactString expected =
    Decode.string
        |> Decode.andThen
            (\actual ->
                if actual == expected then
                    Decode.succeed actual

                else
                    Decode.fail "Unexpected value"
            )

Generated/Dog.elm

-- Generated by elm-openapi-codegen. Do not edit.
module Generated.Dog exposing (Dog, dogDecoder)

import Json.Decode as Decode exposing (Decoder)
import Json.Decode.Pipeline exposing (required)


type alias Dog =
    { barkVolume : Int
    , name : String
    , petType : String
    }


dogDecoder : Decoder Dog
dogDecoder =
    Decode.succeed Dog
        |> required "barkVolume" Decode.int
        |> required "name" Decode.string
        |> required "petType" (exactString "dog")


exactString : String -> Decoder String
exactString expected =
    Decode.string
        |> Decode.andThen
            (\actual ->
                if actual == expected then
                    Decode.succeed actual

                else
                    Decode.fail "Unexpected value"
            )

Generated/Pet.elm

-- Generated by elm-openapi-codegen. Do not edit.
module Generated.Pet exposing (Pet(..), petDecoder)

import Generated.Cat exposing (Cat, catDecoder)
import Generated.Dog exposing (Dog, dogDecoder)
import Json.Decode as Decode exposing (Decoder)


type Pet
    = PetCat Cat
    | PetDog Dog


petDecoder : Decoder Pet
petDecoder =
    Decode.field "petType" Decode.string
        |> Decode.andThen
            (\value ->
                case value of
                    "cat" ->
                        Decode.map PetCat catDecoder

                    "dog" ->
                        Decode.map PetDog dogDecoder

                    other ->
                        Decode.fail ("Unknown Pet: " ++ other)
            )

allOf

Object schemas composed with allOf are flattened into one generated record.

Book:
  allOf:
    - $ref: '#/components/schemas/CatalogItem'
    - type: object
      properties:
        authorName:
          type: string
        isbn:
          type: string
CatalogItem:
  type: object
  properties:
    itemId:
      type: string
    title:
      type: string

Generated/Book.elm

-- Generated by elm-openapi-codegen. Do not edit.
module Generated.Book exposing (Book, bookDecoder)

import Json.Decode as Decode exposing (Decoder)
import Json.Decode.Pipeline exposing (optional)


type alias Book =
    { itemId : Maybe String
    , title : Maybe String
    , authorName : Maybe String
    , isbn : Maybe String
    }


bookDecoder : Decoder Book
bookDecoder =
    Decode.succeed Book
        |> optional "itemId" (Decode.map Just Decode.string) Nothing
        |> optional "title" (Decode.map Just Decode.string) Nothing
        |> optional "authorName" (Decode.map Just Decode.string) Nothing
        |> optional "isbn" (Decode.map Just Decode.string) Nothing

Generated/CatalogItem.elm

-- Generated by elm-openapi-codegen. Do not edit.
module Generated.CatalogItem exposing (CatalogItem, catalogItemDecoder)

import Json.Decode as Decode exposing (Decoder)
import Json.Decode.Pipeline exposing (optional)


type alias CatalogItem =
    { itemId : Maybe String
    , title : Maybe String
    }


catalogItemDecoder : Decoder CatalogItem
catalogItemDecoder =
    Decode.succeed CatalogItem
        |> optional "itemId" (Decode.map Just Decode.string) Nothing
        |> optional "title" (Decode.map Just Decode.string) Nothing

Recursion

Recursive schemas generate recursive Elm types and lazy decoders.

Comment:
  type: object
  required:
    - author
    - body
  properties:
    author:
      type: string
    body:
      type: string
    replies:
      type: array
      items:
        $ref: '#/components/schemas/Comment'

Generated/Comment.elm

-- Generated by elm-openapi-codegen. Do not edit.
module Generated.Comment exposing (Comment, commentDecoder)

import Json.Decode as Decode exposing (Decoder)
import Json.Decode.Pipeline exposing (optional, required)


type Comment
    = Comment
        { author : String
        , body : String
        , replies : Maybe (List Comment)
        }


commentDecoder : Decoder Comment
commentDecoder =
    Decode.lazy
        (\_ ->
            Decode.succeed
                (\author body replies ->
                    Comment
                        { author = author
                        , body = body
                        , replies = replies
                        }
                )
                |> required "author" Decode.string
                |> required "body" Decode.string
                |> optional "replies" (Decode.map Just (Decode.list commentDecoder)) Nothing
        )

Clone this wiki locally