As I used it more and more in my work, I became increasingly aware of its importance.
Exposing the software's state and operations through APIs greatly improves the debugging experience, provides extensibility, and makes it very convenient for other programs to call them.
On the other hand, centering on APIs can also improve program structure, because the entire program is written around a single context.
Currently, I usually use HTTP as the external interface because it allows for operations using curl and exposes these operations to the front end.
Previously, I used Axum as the HTTP server and utoipa to export the API to OpenAPI. Then, I used tools to convert the OpenAPI as TypeScript code for front-end.
However, I quickly encountered some problems. First, utoipa's documentation isn't generated during the build process; I need to run `cargo test` separately to generate the OpenAPI documentation. Second, utoipa's procedural macros are sometimes complex than the functions themselves. Finally, Axum's type system is overly complex, making every interface writing or modification a painful experience.
Furthermore, while OpenAPI to TypeScript tools are available, their quality is often inconsistent, and the generated code is rarely usable.
I'm hoping for a tool that generates Rust/OpenAPI/TypeScript code by writing something like a proto file. For Rust, ideally, it would generate a trait, so implementing the trait would automatically implement the HTTP interface. In other words, I'd like a tool like this:
```
interface API {
@get
void hello_world();
@post
string hello_world2();
};```
I've carefully studied tools like gRPC/TypeSpec, but I'm not entirely satisfied.
Since I have prior experience writing parsers and code generation tools, I finally decided to create my own—[XIDL](https://github.com/xidl/xidl). I made the following improvements:
First, I generated the trait and OpenAPI documentation using `xidl-build`, thus resolving the inconsistency in OpenAPI generation time.
Second, I exposed the HTTP interface as an asynchronous trait, hiding its internal complexity within the generated codes. This eliminates the need for developers to struggle with Axum's complex types.
Furthermore, I strictly defined the interface behavior using RFCs, ensuring consistent presentation across different languages. Simultaneously, I used [behave](http://behave.readthedocs.io/en/stable/) and [hurl](http://hurl.dev/) to ensure interoperability among all generators.
Furthermore, I wrote a simple [LSP](https://github.com/xidl/idl-language-server) that allows real-time preview of the OpenAPI interface via scalars. This enables direct HTTP API calls within the browser.
invincible703•54m ago