29. 09. 2025 Oscar Zambotti Front-end, Vue

Summoning Orval: Binding Backend and Frontend by Magic

When building modern web applications, type safety and API consistency are essential. Instead of manually writing API clients and models (and risking drift between backend and frontend), you can automate the process using OpenAPI and Orval.

In this post, we’ll focus on how to generate TypeScript functions and interfaces using Orval, starting from an openapi.json description file.

What is Orval?

Orval is a powerful RESTful client generator designed to streamline frontend development by automating the creation of TypeScript clients from OpenAPI v3 or Swagger v2 specifications.

Orval helps developers by generating typed API clientsTypeScript models from API schemas, HTTP request functions using different clients – and it can even mock up using MSW (Mock Service Worker) for frontend testing. This means:

  • No more hand-written boilerplate
  • No more mismatched types between backend and frontend
  • Faster development and safer refactoring

The Ritual of Summoning

a.k.a. the Workflow in a Nutshell:

Backend → openapi.json → Orval → Typed API Client + Models → Vue App

In our case, we have a backend – written in Rust with Rocket and okapi – that generates openapi.json, where Orval then consumes that spec and generates the client part (used in our frontend) built with Vue.js.

The Orval Configuration Scroll

Here’s an example of the configuration we use in orval.config.ts:

import { defineConfig } from 'orval';

export default defineConfig({
  satayo2fetch: {
    input: {
      target: 'openapi.json'
    },
    output: {
      mode: 'single',
      client: 'axios',
      workspace: 'src/api/',
      target: './client.ts',
      schemas: './models',
      baseUrl: '/api',
      prettier: true,
      clean: true
    },
    hooks: {
      afterAllFilesWrite: [
        'prettier --write',
        'eslint --fix'
      ]
    }
  }
});

Key Points:

  • output.client: we use axios (and we’ll explain below why this is better than fetch)
  • output.mode 'single': generates one client file plus a folder for models
  • hooks: automatically formats and lints the generated code

Running Orval with npx orval --config ./orval.config.ts will create:

src/api/
  client.ts   // All API functions
  models/     // TypeScript interfaces from OpenAPI schemas

Trading fetch for axios

We initially generated a fetch-based client, but quickly realized axios was a better fit for production. Why?

  • Interceptors: you can easily add auth tokens, refresh logic, and global error handling
  • Error Handling: axios rejects on HTTP errors and provides structured error objects
  • Progress Events: useful for file uploads/downloads
  • Mutator Pattern: Orval integrates nicely with custom axios instances for advanced setups

In short, axios gives you a battle-ready toolkit for real-world apps, while fetch is fine for simpler cases.

CI/CD Integration

To keep your client in sync with the backend contract, you need a repeatable process that guarantees the generated code always reflects the latest OpenAPI specification. This avoids type mismatches, runtime errors, and the dreaded “works on my machine” scenario.

So here’s a flow I can recommended for you:

Generate the OpenAPI spec from the backend

The backend should produce an openapi.json file as part of its build or release process. This can be done by exposing an endpoint (e.g., /openapi.json) or exporting the file during CI.

Make the spec available to the frontend

  • In a monorepo, copy the file into the frontend folder as part of the pipeline.
  • In a polyrepo, download it from a published artifact or a trusted URL. The key is to ensure the frontend always uses the latest version of the spec.

Run Orval to generate the client

This step regenerates the TypeScript client and models based on the updated spec.

Build and test

Run your usual build and test steps. If the generated client introduces breaking changes, TypeScript will catch them during compilation, giving you early feedback.

The Lorekeeper’s Closing Words

By using Orval, your frontend becomes type-safe, maintainable, and future-proof. The backend can evolve, and as long as the OpenAPI spec is updated, your client stays in sync: no manual work, no guesswork.

So ends this tale of typed enchantments and automated conjuring… until the next deployment awakens the need for new magic.

These Solutions are Engineered by Humans

Did you find this article interesting? Are you an “under the hood” kind of person? We’re really big on automation and we’re always looking for people in a similar vein to fill roles like this one as well as other roles here at Würth Phoenix.

Oscar Zambotti

Oscar Zambotti

Software Engineer in the R&D Team of the IT System & Service Management Solutions group, Würth Phoenix. Random trivia: from Trentino (Italy), in love with everything is technology, gamer, TV shows enthusiast, AC Milan supporter, once a DJ, but most of all father and husband.

Author

Oscar Zambotti

Software Engineer in the R&D Team of the IT System & Service Management Solutions group, Würth Phoenix. Random trivia: from Trentino (Italy), in love with everything is technology, gamer, TV shows enthusiast, AC Milan supporter, once a DJ, but most of all father and husband.

Leave a Reply

Your email address will not be published. Required fields are marked *

Archive