October 23rd, 2024

Toasty, an Async ORM for Rust

Toasty is a new asynchronous ORM for Rust, supporting SQL and NoSQL databases. It focuses on ease of use, allowing users to define data models and generate Rust code, inviting feedback for improvement.

Read original articleLink Icon
ConfusionSkepticismInterest
Toasty, an Async ORM for Rust

Toasty is a new asynchronous Object-Relational Mapping (ORM) tool for the Rust programming language, designed to simplify database interactions. Currently in its early development phase, Toasty supports both SQL and NoSQL databases, including Sqlite and DynamoDB, with plans to add Cassandra soon. The tool is not yet available on crates.io and is considered a preview version, inviting user feedback for further development. Users begin by defining their data model in a schema file, which Toasty then uses to generate the necessary Rust code. The focus of Toasty is on ease of use, addressing a gap in Rust's ecosystem where existing ORM libraries often prioritize performance over usability. The generated code aims to minimize complexity, avoiding excessive use of Rust's traits and lifetimes, and opting for explicit code generation rather than procedural macros to enhance readability and discoverability. While Toasty does not abstract the differences between SQL and NoSQL databases, it provides a standard feature set for basic operations and allows for database-specific optimizations. The developer encourages users to experiment with Toasty and provide feedback, with the goal of preparing it for real-world applications by the end of next year.

- Toasty is an asynchronous ORM for Rust, currently in early development.

- It supports both SQL and NoSQL databases, including Sqlite and DynamoDB.

- The tool emphasizes ease of use over performance, addressing gaps in existing Rust ORM libraries.

- Users define data models in schema files, and Toasty generates corresponding Rust code.

- Feedback from users is encouraged to refine the API and prepare for real-world use.

AI: What people are saying
The comments on the article about Toasty, the new asynchronous ORM for Rust, reveal a mix of opinions and concerns from users.
  • Many users find the syntax and method naming confusing, suggesting clearer differentiation for property access.
  • Some commenters express skepticism about the effectiveness of ORMs in general, citing issues like the n+1 query problem.
  • There are comparisons to existing ORMs like Diesel and SeaORM, with some users preferring these established options.
  • Several users question the need for a custom schema definition file, advocating for defining models directly in Rust.
  • Overall, there is a divide between those excited about the potential of Toasty and those who prefer traditional SQL approaches.
Link Icon 23 comments
By @alilleybrinker - 6 months
Very interested in exploring how this will compare to Diesel [1] and SeaORM [2], the other two options in this space today. Joshua Mo at Shuttle did a comparison between Diesel and SeaORM in January of this year that was really interesting [3].

[1]: https://diesel.rs/

[2]: https://www.sea-ql.org/SeaORM/

[3]: https://www.shuttle.dev/blog/2024/01/16/best-orm-rust

By @OtomotO - 6 months
ORM has never worked for me in any language.

Sooner or later we always hit the n+1 query problem which could only be resolved by a query builder or just plain old sql.

It always was a mess and these days I can't be bothered to try it even anymore because it has cost me a lot of hours and money.

By @xpe - 6 months
I wish the following three paragraphs were widely read and understood by all software developers, especially web developers:

> The common wisdom is to maximize productivity when performance is less critical. I agree with this position. When building a web application, performance is a secondary concern to productivity. So why are teams adopting Rust more often where performance is less critical? It is because once you learn Rust, you can be very productive.

> Productivity is complex and multifaceted. We can all agree that Rust's edit-compile-test cycle could be quicker. This friction is countered by fewer bugs, production issues, and a robust long-term maintenance story (Rust's borrow checker tends to incentivize more maintainable code). Additionally, because Rust can work well for many use cases, whether infrastructure-level server cases, higher-level web applications, or even in the client (browser via WASM and iOS, MacOS, Windows, etc. natively), Rust has an excellent code-reuse story. Internal libraries can be written once and reused in all of these contexts.

> So, while Rust might not be the most productive programming language for prototyping, it is very competitive for projects that will be around for years.

By @the__alchemist - 6 months
Et tu, toasty?

As time passes, the more I feel a minority in adoring rust, while detesting Async. I have attempted it a number of times, but it seems incompatible with my brain's idea of structure. Not asynchronous or concurrent programming, but Async/Await in rust. It appears that most of the networking libraries have committed to this path, and embedded it moving in its direction.

I bring this up because a main reason for my distaste is Async's incompatibility with non-Async. I also bring this up because lack of a Django or SQLAlchemy-style ORM is one reason I continue to write web applications in Python.

By @didip - 6 months
I think the custom schema definition file is not needed. Just define it in plain Rust. Not sure what the win is for this tool.
By @Ciantic - 6 months
It is nice to see more ORMs, but inventing a new file format and language `toasty` isn't my cup of tea. I'd rather define the models in Rust and let the generator emit more Rust files.

Creating your own file format is always difficult. Now, you have to come up with syntax highlighting, refactoring support, go to definition, etc. When I prototype, I tend to rename a lot of my columns and move them around. That is when robust refactoring support, which the language's own LSP already provides, is beneficial, and this approach throws them all away.

By @Sytten - 6 months
For me diesel hits right balance since it is more a query builder and it is close to the SQL syntax. But sometimes it doesn't work because it is very strongly typed, right now I use sea-query for those scenarios and I built the bridge between the two.

Ideally I would use something akin to Go Jet.

By @colesantiago - 6 months
I don't get the pent up anger with ORMs, I used it for my SaaS on Flask that I run and own for 4 years bringing in over $2M+ ARR with no issues.

Great to see some development in this for Rust, perhaps after it becomes stable I may even switch my SaaS to it.

By @aabhay - 6 months
Interesting take!

In my experience, Dynamo and other NoSQL systems are really expressive and powerful when you take the plunge and make your own ORM. That’s because the model of nosql can often play much nicer with somewhat unique structures like

- single table patterns - fully denormalized or graph style structures - compound sort keys (e.g. category prefixed)

Because of that, I would personally recommend developing your own ORM layer, despite the initial cost

By @satvikpendem - 6 months
Looks similar to Prisma Client Rust but because Prisma and its file format are already established unlike toasty files, might be easier to use that. However, this is by Tokio and PCR is relatively unknown with development being not too fast, so your mileage may vary. I've been using diesel (with diesel_async) so far.
By @ericyd - 6 months
I find the syntax confusing. Setting properties and even creating associated model instances is done with opaque method names like `.name()` and `.todo()`. I'm not always a fan of using set/get prefixes, but I think there should be some differentiation for an ORM which is inherently involved in property access. I'm particular it is strange and surprising to me that `.todo()` would associate another model. Why not "add_todo" or "create_todo"? What if the association is not one to many but one to one? The method `.todos()` retrieves a list of Todos, but what if we're talking about a 1:1 Profile model? How would a user differentiate between setting and getting a `.profile()`?

I'm not a rust person so I might just be exposing my ignorance here, just wanted to provide feedback since it's on early development.

By @cutler - 6 months
Why, oh why? Just SAY NO TO ORMs, especially in non-OO languages.
By @tricked - 6 months
Looks well thought out i like that for the most part this seems faster/easier than rolling your own sql query mapping etc compared to the other solutions I've come across in rust
By @isodev - 6 months
Nice, I love it!

It reminds me of Prisma and yet, it's all Rust. Also good to see that async is the focus point of the API so the usage feels ergonomic.

By @cyndunlop - 6 months
Toasty was the focus of Carl Lerche's P99 CONF keynote on Wednesday. It provoked some interesting discussion in the chat.
By @arandomusername - 6 months
Looks awesome. Would love to see the table definitions that are generated from the schema as well.
By @fulafel - 6 months
Why is asynchronity (sp?) a concern of the ORM in this case?
By @revskill - 6 months
O in orm is misleading term. To me orm is about table.
By @dvdbloc - 6 months
Is it just me or why does Rust have all these confusing names that seemingly have nothing to do with the functionality of the module/crate? Or maybe I’m just used to the names in Python and C++ packages for performing common tasks. It just seems to make it harder for a newcomer to locate what packages they should be using when they want to perform some common function.
By @jruz - 6 months
Meh, the article makes it sound as if there were nothing and we have already solid options like SeaORM and Diesel.

Still to me they all suck and nothing beats SQLx

By @andrewstuart - 6 months
The days of the ORM have passed.

AI writes amazing SQL, modern SQL databases are incredible and the best way to get the most out of your DB is write SQL.

Invest your learning budget in SQL, not in some random developers abstraction.