aj-foster

aj-foster

OpenAPI Generator - Generate client code from an OpanAPI description

Background

OpenAPI is a standard for documenting API resources. Libraries like Spex allow you to generate OpenAPI descriptions of your endpoints to share with consumers. Then, the OpenAPI community provides a series of code generators that take the API descriptions and create client code (for example, one function per API endpoint). They even support Elixir.

However, I was not satisfied with the code generation options available for Elixir. I craved more flexibility in the outputted code, and better ergonomics of the resulting libraries. Being written in Elixir would also be a bonus.

So, I created OpenAPI Generator for Elixir. It accepts an existing OpenAPI description and generates client code for the API endpoints.

What does it do?

After installing the project as a development-only dependency and adding your configuration, it provides a task mix api.gen which accepts an OpenAPI description document and writes formatted code inside of your project.

The generator aims to be highly configurable, allowing you to repeatably rename, merge, and ignore parts of the OpenAPI description. This way you can create more ergonomic client code regardless of any weird parts of the original API description. For example, GitHub’s OpenAPI 3.0 description had to make use of NullableRepository and other repetitive schemas that would only confuse users of the client code. Such a schema can easily be merged into the Repository or FullRepository schemas. (Also, those two schemas could be combined into two typespecs with a single struct definition.)

With this kind of careful configuration, client code maintainers can create libraries that have the ergonomics of a hand-crafted library while also keeping the maintainability of generated code. GitHub, as an example, has too many API endpoints to maintain by hand — but we shouldn’t have to sacrifice usability for the sake of automated code generation.

Learn more

Check out the repository and join the discussions tab with thoughts and feedback.

Most Liked

aj-foster

aj-foster

I’m pleased to share that I will be discussing this library at ElixirConf US 2023 in a talk titled Filling the Gaps in the Ecosystem. The initial schedule is below (subject to change):

Date: Wednesday, 6 September 2023
Time: 2:15pm ET
Location: Palm AB

Would love to see and chat with anyone who uses this project. And if there’s anything you’d like to hear about in the conference talk, please let me know!

11
Post #7
ityonemo

ityonemo

I highly disrecommend going the codegen route on this,my experience is it becomes extremely finicky to get deployment and code control right on this, tbh this is a strong case for macros. Full disclosure, I was planning on doing an OpenAPI client compiler immediately after I finish my server router compiler, if you want to collaborate dm me.

maartenvanvliet

maartenvanvliet

I’ve worked on a Stripe SDK (Stripe — Striped v0.5.0) though the code is now merged with the StripityStripe library. It generates the code from the api spec at compile time.

Also found that it is finicky, all public open api schemas seem to do things a little differently if you want to generate an idiomatic sdk. E.g Stripe doesn’t use the tags functionality of the spec which would have been useful. So, the customisability your library has is a big plus here.

aj-foster

aj-foster

I think you may be confused about the relationship between this project and the code it generates. This is something I will work to clarify in the readme and documentation.

This OpenAPI generator project is responsible for creating two types of modules: schemas and operations. In the example GitHub client, these modules can be found in lib/schemas and lib/operations. Everything outside of these directories is not generated code.

If you look through the modules in those directories, you will find no references to any HTTP client at all. In fact, the contract is a very general call to client.request/1, where client is a module configured or passed in as an option to the API operation. It is expected that a client library author (the customer of this project) will define their own client module using whatever tools they see fit.

In the GitHub client example, I’ve deliberately created a bring-your-own library system where anyone can define plugins to use any HTTP client they wish. It just so happens that I’ve only written an HTTPoison client out of the box for now.

aj-foster

aj-foster

Thanks for the feedback. I decided to go this route for various reasons, and I’m quite happy with the results so far. You may have different needs, or intend to use the client code in a different context (directly in an application instead of as a separate client library). There’s room for all of these methods in the community.

Where Next?

Popular in Libraries Top

mhanberg
I just released the first version of Temple: an HTML DSL for Elixir and Phoenix! You can read this blog post or the docs for more info...
New
seancribbs
Today I released a new dialyzer Mix task as the dialyzex package! At the time we started writing this task, the existing dialyzer integra...
New
sasajuric
I’d like to announce a small library called boundaries. This is an experimental project which explores the idea of enforcing boundaries ...
New
nikokozak
Hello all, I’ve been working on Svonix - a library for quickly integrating Svelte components into Phoenix views. It’s a much-needed succ...
New
KronicDeth
Elixir plugin for JetBrain’s IntelliJ Platform (including Rubymine) This is a plugin that adds support for Elixir to JetBrains IntelliJ...
289 35421 110
New
aditya7iyengar
Rummage.Ecto and Rummage.Phoenix provide ways to perform Searching, Sorting and Pagination over Ecto queries and Phoenix collections. Fo...
New
martinthenth
Hello everybody :wave: Recently, some of my colleagues talked about database ids and uuids and their problems, and I remembered the pain...
New
Jskalc
Hi! Today, after a couple weeks of development I’ve released v0.1 of LiveVue. It’s a seamless integration of Vue and Phoenix LiveView, i...
New
alisinabh
Hey everyone i’ve developed a library for Jalaali calendar for elixir which supports converting Gregorian dates to Jalaali and vice vers...
New
ostinelli
Let’s write a database! Well not really, but I think it’s a little sad that there doesn’t seem to be a simple in-memory distributed KV da...
New

Other popular topics Top

sergio
In Ruby, I can go: User.find_by(email: "foobar@email.com").update(email: "hello@email.com") How can I do something similar in Elixir? ...
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
lessless
I believe there are people here who are dealing with CSV files import on the daily basis, and since Excel is a really popular tool there ...
New
Jim
As a follow up to my earlier question: I have the code compiling and running but not getting a successful login from the rest server. ...
New
fireproofsocks
I’m working on defining a simple Ecto schema for a table (in PostGres), but I don’t see where I can define a column as NOT NULL. Conside...
New
chrismccord
As promised, the first release candidate of Phoenix 1.3.0 is out! This release focuses on code generators with improved project structure...
New
myronmarston
The Elixir Typespec docs show the following syntax for keyword lists in typespecs: # ... | [key: type] # keyword lis...
New
chrisalley
ExUnit now has describe blocks which is a welcome addition coming from RSpec. In the docs, it states that nested hierarchies of describe ...
New
belgoros
I’m not a pro in using Regex and can’t figure out why the following behaviour happens, especially if we take into account the difference ...
New
magnetic
Hey :wave:t3: Elixir community, I’ve been learning Elixir, and working on some side projects. My editor of choice is VSCode, and althoug...
New

Sub Categories:

We're in Beta

About us Mission Statement