Crates.io GitHub Workflow Status GitHub codecov

Ultime

The ultimate full-stack experience.

Warning This project is in early preview.

This project can be used as a CLI:

cargo install ultime

Architecture

This project includes features that will give you a faster and better development workflow using the following tech stack:

The main feature is the automatic of code generation based on your SurrealDB schemas and queries. An ultime project should look like this:

Get started

First, you need to create a new project using one of the predefined templates. So, for example:

ultime new my-blog --template blog

A new directory will be created. You can cd to this new directory and run the following command:

ultime

This command will:

Automatic code generation of models

As of now, it is not possible to automatically detect the output of a .surql file: queries or mutations. However, a type is automatically generated for you so that all you need is to define the properties of this type. All models should be defined in the /src/models folder.

Here is an example of the model definition from the response of /queries/posts.surql query:

```rust use serde::{Deserialize, Serialize};

[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]

pub struct PostsQueryItem { pub id: String, pub title: String, pub content: String, pub status: String, pub numberofcomments: u16, }

pub type PostsQuery = Vec; ```

Another example from the response of /mutations/comment.surql query:

```rust use serde::{Deserialize, Serialize};

[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]

pub struct CommentMutationItem { pub id: String, pub content: String, }

pub type CommentMutation = Vec; ```

Query/Mutation variables extraction

In order to differentiate internal variables and input variables, we established a pattern to follow in order to successfully extract query and mutation variables.

The following mutation...

```sql // $userid: &str // $postid: Option // $comment_id: Option // $content: &str

LET $user = (SELECT * FROM type::thing("user", $user_id));

LET $postorcomment = (SELECT * FROM type::thing("post", $postid), type::thing("comment", $commentid));

RELATE $user->comment->$postorcomment SET content = $content; ```

...will generate this function:

```rust pub async fn mutatecomment( db: &' Surreal, userid: &str, postid: Option, commentid: Option, content: &str ) -> Result { const QUERY: &str = includestr!("../../../mutations/comment.surql");

let result: CommentMutation =  db
    .query(QUERY)
    .bind(("user_id", user_id))
    .bind(("post_id", post_id))
    .bind(("comment_id", comment_id))
    .bind(("content", content))
    .await?
    .take(0)?;

Ok(result)

} ```

As you can see, comments should follow the rules:

Predefined templates

To help you get started quickly, there is a list of predefined templates you can use:

| Template | Description | | --------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | empty | The smallest ultime project you can create.
A clean schema with an already defined script_migration table to store the applied migrations.
A basic leptos app with a Counter example. | | blog | A blog app: create new blog posts, publish/unpublish posts and comments. |

You can create a new ultime project using the following command line:

ultime new <PROJECT_NAME> --template <TEMPLATE>