Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

New generate macro #3

Merged
merged 4 commits into from
Aug 16, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
55 changes: 26 additions & 29 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -121,17 +121,18 @@ async fn book_state() -> Json<BookState> {
}
```

### Step 2: Add Routes
Use the `route!` macro with `axum`'s Router to add routes. This enables the `generate!` macro to identify the route and generate corresponding functions, structs, types, and enums. Note that inline functions cannot be used because the function names in the generated TypeScript file are inferred from the handler function names.
### Step 2: Add Routes && Generate Api

```rust
Use the `generate!` macro to define your router and other telemetry to generate the Api. You have to define the `output` location of the TypeScript file and the `routes`. Note that inline functions cannot be used in the `router` field because the function names in the generated TypeScript file are inferred from the handler function names.

```rust, ignore
use axum::{
routing::get,
Json,
Router,
extract::Path,
};
use gluer::{route, metadata};
use gluer::{generate, metadata};

// without `#[metadata]`, it's non-API-important
async fn root() -> String {
Expand All @@ -144,26 +145,22 @@ async fn hello(Path(h): Path<String>) -> Json<String> {
h.into()
}

let mut app: Router<()> = Router::new()
// Add non-API-important directly on the router
.route("/", get(root));
// Add API-important routes with the route macro
route!(app, "/:hello", get(hello));

let mut app: Router<()> = generate! {
routes = {
// Add API-important inside the routes field
"hello" = get(hello),
},
output = "tests/api.ts",
}
// Add non-API-important outside the macro
.route("/", get(root));
```

### Step 3: Generate API

Generate the API file using the `generate!` macro. This macro generates the TypeScript file during macro expansion (compile time). You need to specify the `project_paths` of your current project, which can be a root directory (represented by `"src"`), multiple directories, or specific files (e.g., `["dir0", "dir1", "dir2/some.rs"]`). The `project_paths` will be scanned to retrieve project data, meaning collecting the information marked by the `route!` and `#[metadata]` macros. Additionally, you need to provide a `path` where the generated file will be saved, including the filename, and a `base` URL for the API. The base URL should not end with a slash (`/`); use `""` for no base URL if you are utilizing `axum`'s static file serving, or provide a URL like `"http://localhost:8080"` for a local server.

```rust
use gluer::generate;
### More Notes

// Make sure to change "tests" to "src" when copying this example into a normal project
generate!("tests", "tests/api.ts", "");
```
The `generate!` macro includes several optional fields, such as `prefix`, which allows you to modify the URL prefix. By default, this value is set to `""`, but you can change it to something like `"/api"`. Please note that the `prefix` should not end with a `/`. Additionally, you can customize the `files` field to specify the Rust project directories containing the source files that define the handler functions and dependencies. This can be a single string literal (e.g., `"src"`) or an array of string literals (e.g., `["src/db", "src"]`). These paths are used to extract type information for the TypeScript client. The default for it is `"src"` which should work in most cases.

And now you can just simply use the router to start your server or do different things, the API should be already generated by your LSP!
And now you can just simply use the router generated by the macro to start your server or do different things, the API should be already generated by your LSP!

## Complete Example

Expand All @@ -172,10 +169,9 @@ Below is a complete example demonstrating the use of `gluer` with `axum`:
```rust
use axum::{
extract::{Path, Query},
routing::get,
Json, Router,
};
use gluer::{generate, metadata, route};
use gluer::{generate, metadata};
use serde::{Deserialize, Serialize};
use std::collections::HashMap;

Expand Down Expand Up @@ -258,13 +254,14 @@ type S = String;

#[tokio::main]
async fn main() {
let mut _app: Router = Router::new();

route!(_app, "/:p", get(fetch_root).post(add_root));
route!(_app, "/char/:path/metadata/:path", get(get_alphabet));

// Make sure to change "tests" to "src" when copying this example into a normal project
generate!("tests", "tests/api.ts", "");
let _app: Router<()> = generate! {
routes = { // required
"/:p" = get(fetch_root).post(add_root),
"/char/:path/metadata/:path" = get(get_alphabet),
},
files = "tests", // Make sure to remove this when copying this example into a normal project
output = "tests/api.ts", //required
};

let _listener = tokio::net::TcpListener::bind("127.0.0.1:8080")
.await
Expand Down
Loading