lud

lud

Oaskit - OpenAPI 3.1 based validation for Phoenix

Hello!

I’ve been working on the Oaskit library for a while now, and just released a first version.

Since I’ve built JSV I wanted to be able to use the latest JSON schemas specifications with OpenAPI, which is possible since version 3.1.

The OpenAPI specification 4.0 has been delayed, and the 3.2 is on its way, so I needed a solid foundation to support those in the future. Also, I have the feeling that next iterations of the spec will have more LLM-oriented features, so I wanted to be able to follow those evolutions with ease.

What is it?

Oaskit is heavily inspired from OpenApiSpex.

It is a set of macros and plugs that automatically validate incoming HTTP requests based on OpenAPI specifications.

It is built around JSON Schema validation provided by JSV and the operation macro.

Key features

  • Request validation plug.
  • Leverages JSV error formatter in API responses. An HTML error page is also built-in if you need it (a must have for user-facing prototypes).
  • Spec generation from router paths.
  • Supports specs from JSON documents or arbirary elixir code.
  • Spec JSON generation. Not supporting YAML at the moment, and I don’t plan to. But I’d be happy to open for custom formatters in the codebase.
  • Test helper to validate responses in your tests.

Missing features

A couple things are missing and on the roadmap:

  • A JSON schema for the built-in error formatter, so you can build 400/415/422 errors in your client generators. My team uses Orval and it’s pretty neat.
  • A controller to serve the JSON spec, and maybe a controller to serve SwaggerUI or Redoc, though I never use those but I know some love it.
  • Header validation (Never used it either, as we generally put validation plugs after the authentication/negociation plugs).

I’m also open for ideas!

Quick example

Here’s what defining an operation looks like:

defmodule MyAppWeb.UserController do
  use MyAppWeb, :controller

  operation :create,
    summary: "Create a new user",
    request_body: {CreateUserAttrsSchema, description: "The user payload"},
    responses: [
      created: UserSchema,
      unprocessable_entity: ErrorSchema
    ]

  def create(conn, _params) do
    # ...
  end
end

Getting started

If you want to try it for yourself, the Quickstart Guide covers everything you need to get up and running!

Current status

This is an early release, so while it’s functional and tested, it may have shortcomings and bugs. I need to test it thoroughly in production before calling it production ready.

I’d love to hear your thoughts! Any feedback, bug reports, or feature requests are welcome!

Thanks for reading!

Most Liked

lud

lud

Hey everyone!

This is an important update for Oaskit with one breaking change!

The library can now automatically delegate authorization of requests to a custom plug of yours, using the security requirements defined on operations.

Please read this post before upgrading if you’re using the library.

The security requirements definitions on operations are now checked. If your OpenAPI specification defines security options, Oaskit will now expect a custom plug that you provide to authorize requests.

From now on, Oaskit will automatically respond to requests on those operations with a 401 HTTP Error unless you provide a custom plug to handle authorization.

This is all covered in a new security guide.

To keep the current behaviour of the library (not verifying authorization), please update your code to set the :security option to false.

plug Oaskit.Plugs.ValidateRequest,
  security: false

Security is important so any feedback will be highly appreciated! Also, many thanks to @MrYawe for the motivation and the bug reports :hugs:

Changelog

[0.6.0] - 2025-10-11

:rocket: Features

  • Added operation-level security check using user-defined plugs
  • Added support for root level security requirements
  • [breaking] Handling security is now mandatory

:bug: Bug Fixes

  • Ensure response body is a binary in Oaskit.Test.valid_response (#23)
  • Fixed normalization of %Reference{} structs

How do I know if I am concerned by this update?

You are concerned if your OpenAPI specification defines security at the root level:

---
openapi: 3.1.1
info:
  title: Oaskit Security API
  version: 0.0.0
servers:
- url: http://localhost:5001/
# Global security
security:
- global:
  - some:global1
  - some:global2

Or at the operation level:

---
openapi: 3.1.1
info:
  title: Oaskit Security API
  version: 0.0.0
servers:
- url: http://localhost:5001/
paths:      
  "/example":
    post:
      operationId: "..."
      # Operation Level security
      security:
      - someApiKey:
        - some:scope1
        - some:scope2
      responses:
        '200':
          content:
            application/json:
              schema: {}
          description: "..."

You are also concerned if your were using the operation macro by passing the :security option (which was not used but could be defined):

operation :create_post,
  operation_id: "CreatePost",
  request_body: PostSchema,
  security: [%{api_key: ["post:read", "post:create"]}]

def create_post(conn, _) do
  # ...
end

Thank you for using Oaskit! Have a nice evening :slight_smile:

lud

lud

I just released version 0.2 with a guide on how to use the library with an existing OpenAPI JSON document instead of defining the operations in the controller: Using an External Specification — oaskit v0.2.0 cc @mayel .

(Spoiler, there is still a tiny macro to use).

lud

lud

I’ve just released a new version with a controller that can serve the spec and Redoc ui :slight_smile:

Asd

Asd

Hi, nice library. I have one question:
It looks very very very similar to open_api_spex. Whats the difference between your library and open_api_spex and why/when should I choose your one?

lud

lud

Hello,

Yes it’s very inspired from OpenApiSpex, basically the same thing. OpenApiSpex is based on OpenAPI 3.0 and Oaskit on OpenAPI 3.1.

Those two version are not really compatible infortunately. 3.1 works with standard JSON schemas and I needed that so I built Oaskit.

Where Next?

Popular in Announcing Top

zachdaniel
Ash Framework 3.0: Official Release! I’m here with the fine folks at Gig City Elixir, pushing the button live on stage :sunglasses: T...
New
shahryarjb
The Chelekom project is a library of Phoenix and LiveView components generated via Mix tasks to fit developer needs seamlessly. One of i...
New
pcharbon
This is a new extension for the Ash framework that lets you use the Commanded library in a more declarative manner and removes most of th...
New
mikehostetler
LLM DB - LLM Model Metadata Package This package was extracted out of the ReqLLM project. LLM DB is a model metadata catalog with fast, ...
New
tugayac
Hey Elixir Community! A few months back, I open sourced a link management system we had built into an app. It’s now got enough features ...
New
webofbits
Helix is a visual workflow designer for AI agents and multi-agent systems, built with Phoenix and React Flow. It provides an intuitive dr...
#ai
New
LostKobrakai
I’ve recently created a small library phoenix_vite integrating the vite build tooling with phoenix. It provides an igniter.installer t...
New
Mati365
Phoenix has great tooling overall, but one thing that’s still lacking is a solid, plug-and-play integration with a modern WYSIWYG editor....
New
fhunleth
Elixir Circuits is a set of libraries for interacting with hardware. We previously announced Circuits.UART, and now we’re ready to announ...
New
volcov
Hello, How is everyone? I hope you’re well =) I worked on a project with some legacy code that existed before Oban’s arrival. This leg...
New

Other popular topics Top

jononomo
I am trying to figure out how Mix knows whether the environment is test, dev, or prod -- where is this set? Thanks.
New
dotdotdotPaul
Okay, I'm having a heck of a time trying to figure out how to best handle the validation of belongs_to associations in Ecto. I'm sure I'...
New
pmjoe
I have a relationship of love and hate with Elixir. Lots of things are just absolutely right, but there are some things that are kind of ...
New
vonH
In asking this question I am more interested about the expressiveness of the language itself and less concerned about the availability of...
New
hariharasudhan94
I would like to know what is the best IDE for elixir development?
New
romenigld
I am trying to run a deploy with docker and I successfully runned with this command: docker build -t romenigld/blog-prod . but when I t...
New
sacepums
Hey guys. I'm new to elixir and im really stocked about it. But I ran into a bit of problem - I need to convert a date sting, for examp...
New
fayddelight
I tried installing elixir 1.11.2 erlang 23.3.4 via asdf in my zsh shell. Enabled the versions locally and globally. When I list them ...
New
beno
I will often find my self writing things similar to: case some_value do nil -> something() "" -> something() _ -> someth...
New
aesmail
Hello guys, I have finally made it. I created an admin interface for a framework. It’s been on my todo list for years and with the curre...
New

We're in Beta

About us Mission Statement