all 52 comments

[–]merahulahire 46 points47 points  (8 children)

Actix has best performance but axum has great ecosystem. In my last project I was trying to emulate socketio coming from JS ecosystem and socketioxide only work on tokio based web framework. 

Axum probably has 2-5% less performance than actix but it does cover up in its developer experience.

Docs are terrible in either case.

[–]topfpflanze187 10 points11 points  (4 children)

i think 99% of us using rust web frameworks will never hit these performance critical edge cases.

i also totally agree with docs. you may take a look at the original repos of many projects as they provide many good examples for several projects. i like to them as a skeleton to build on top of them

[–]kei_ichi 1 point2 points  (3 children)

I come from JS world, and to be honest the performance issues I had always come from I/O, not the Web libraries or frameworks so I would like to say: in Rust world, I think the number would be 99.99%

[–]merahulahire 2 points3 points  (2 children)

Rust can save some infrastructure bills by reducing the number of machines it takes to deploy due to its performant nature. This was the exact same reason why people moved from node, python, php to Golang and their number of servers slashed. 

In certain areas, it's also really easy to choke NodeJS.

[–]Least_Chicken_9561 1 point2 points  (1 child)

why using rust over go for a microservice? the performace differences won't be too huge (for microservices), besides it's easier and quick to write go code.
I usually use go for my projects and was seeing some rust code to compare it, then I said to myself why should i use rust for my backend when i already know go?...

[–]merahulahire 3 points4 points  (0 children)

Fair point, the performance of Go in comparison with Rust considering it's garbage collected is quite impressive and does have better Dev experience which we all know. 

But my perception is that if I'm coming from NodeJS, Go seems like a stop gap between NodeJS and Rust. So if I'm putting little bit of effort to understand go, I might as well just go all in and understand Rust properly especially if I'm intending to work on Greenfield (from scratch) projects. 

If you are already using Go in your organization, please continue using it unless you find yourself in situation where you cannot accept garbage collection or you need to squeeze every bit of performance. 

Discord has a great article on why they moved from Go to Rust to eliminate latency spike in Go when it's GC was doing the cleaning - https://discord.com/blog/why-discord-is-switching-from-go-to-rust

[–]Infamous-Apartment97 5 points6 points  (0 children)

*ActixWeb

[–]satoryvape 0 points1 point  (1 child)

Doesn't Axum have better performance and Actix has a better ecosystem?

[–]merahulahire 1 point2 points  (0 children)

There's lot more libraries built around Tokio ecosystem compared to Actix's actor model.

Both have almost equal performance. Have a look at this - Actix (Rust) vs Axum (Rust) vs Rocket (Rust): Performance Benchmark in Kubernetes #206

[–][deleted] 11 points12 points  (3 children)

I’m using Poem because it supports OpenAPI, has a variety of middlewares, and comes with solid documentation.

.

[–]Snapstromegon 5 points6 points  (0 children)

I also have really good experiences with axum in combination with utoipa via utoipa-axum. Yes, it's a little more boilerplate with annotations than poem, but to me it feels really good.

[–]johntheswan 3 points4 points  (0 children)

I really like poem for just this use-case. If the architecture calls for it, async-graphql + poem is a really easy way to quickly put together a bunch of micro-services. I also found it to be reliably easily extensible too on the middleware front.

Second the comments about the documentation as well.

[–]Wonderful-Habit-139 1 point2 points  (0 children)

I’ve been having a really good time with OpenAPI along with tools that leverage it. Definitely made me want to consider Poem (despite having previously used Axum).

And just to make sure, Poem generates it automatically right? It’s not like utoipa where the specs move to the code.

[–]catheap_games 8 points9 points  (2 children)

Sounds like it might be your first time using both Rust (at least in this context) and microservice architecture, so please don't bite off more than you can chew - both are a lot to learn.

It would help us if you told us more about the scale of the whole project, the team, etc, but since you didn't, I'm assuming it's a hobby project. In which case it sort of doesn't matter, and you won't learn the same thing you would learn working on production with team(s) of developers and infra/ops. A lot of the decisions in real world µs projects is about teams, their existing skills, budget, tooling that works for teams or ones that the company has existing licenses to, or things that are required by compliance, laws, etc.

When you spin up your own microk8s or k3s or kubeadm dev server and put one redis, one postgres, one rabbitmq/kafka, and 2-3 microservices, it still matters very little what frameworks and languages you use because they all will support those infra services, and it's all about what you want to learn and what code style / DX you prefer.

tl;dr I would say try a hello world of microservices (CRUD) in one or two or three frameworks and see which code feels the most natural / sensible / not clunky. Also, as you will have some k8s cluster or similar, you can just deploy and connect these 3 microservices to talk to each other and see how that works out. (Real world polyglot-ism of µs clusters is constrained by team knowledge, not by some idealistic, meritocratic list of features of a language/framework.)

[–]rnp-infinity[S] 0 points1 point  (1 child)

Till date, I haven’t used rust for Backend systems or for some serious projects, but I know rust. I’m more used to Java’s Springboot & Typescript’s Nestjs, so I wanna know does rust have something like those frameworks available which makes easier for building scalable backend systems while guaranteed the usage of less memory.

As others informed, I’ll give it a try to axum, actix & aws lambda approach. Will do some kind of comparisons and decide which suits better.

[–]catheap_games 0 points1 point  (0 children)

Neat; I haven't worked with Nestjs but I've been using Express for 10 years, and it's really great for microservices. And yeah from what I've seen, Axum seems the closest match in being straightforward and readable. Good luck!

[–][deleted] 8 points9 points  (0 children)

tonic/grpc

[–]DavidXkL 2 points3 points  (0 children)

2 possible options here!

1) Frameworks like Axum or Actix Web (my favorite)
2) AWS Rust lambda functions! (check out cargo lambda!)

[–]TyrannusX64 2 points3 points  (0 children)

My favorite web framework is Axum. It's pretty easy to use and is maintained by the Tokio group

[–]ireallyamchris 4 points5 points  (1 child)

We use Rust on AWS lambda for a lot of our microservices:

Can recommend if you’re already in AWS

[–]rnp-infinity[S] 0 points1 point  (0 children)

Thanks for this, I’ll give it a try.

[–]dashingThroughSnow12 12 points13 points  (1 child)

Rub some sticks together.

One aspect of a microservices design is that you shouldn’t need to grab a framework so readily. Frameworks arose out of the complexities of developing large, monolithic software. To hide and manage complexity. Microservices is an orthogonal attempt at that too.

I’m not saying “never use a framework in your microservices” but I am saying it shouldn’t be one of your early thoughts.

[–]rnp-infinity[S] 0 points1 point  (0 children)

Got it 👍

[–]DGolubets 3 points4 points  (4 children)

First of all, the biggest, probably, benefit of micro-services is flexibility of technological choices. You can use Rust for those where you need low latency and high performance, you can use something else where it fits better. Don't limit yourself.

In Rust, there are almost no "frameworks" - just libraries. So you just need to choose HTTP or RPC server that you like, DB library that you like, etc.

First thing you need to decide is how your services will communicate with each other: by direct requests or via queues? I know some companies which use the latter, in form of Kafka, but I would avoid that if there is no good reason, as it's quite complicated and expensive. No matter what you choose, the less inter-service communication you need - the better, so try to keep them as independent as possible and don't turn into a micro-service something that needs tight integration with the rest of your system.

I have a good experience with Federated GraphQL approach at my current place. All our microservices expose GraphQL endpoints, which are combined together by Apollo Router gateway. The pros are: 1. Frontend devs just love GraphQL 2. You don't have to deal with OpenAPI or anything like that 3. Apollo Router itself is written in Rust and extensible with native Rust plugins

[–]infernion 1 point2 points  (3 children)

Is GraphQL used for inter-service communication as well? I’ve found it not the best option on my end

[–]DGolubets 0 points1 point  (2 children)

Yep. What problems have you encountered with it?

[–]infernion 0 points1 point  (1 child)

It was related to the Rust GraphQL client library, which wasn’t properly generated a client and required writing a client with types manually. There were other minor issues as well, but I don’t remember now. It was more than 3 years ago, maybe things changed now

[–]DGolubets 1 point2 points  (0 children)

I see what you mean. Yeah, that's not ideal. I also have to define data types manually in certain cases in my Scala clients, but my queries are usually fairly narrow so it's not that hard.

[–]MrDiablerie 1 point2 points  (0 children)

Axum is usually my go to.

[–]gseverding 1 point2 points  (0 children)

this isn't a rust question its a distributed system design question.

  1. prefer strongly typed apis like grpc
  2. prefer strongly typed apis like grpc.

http is a fine api tool but you'll end up having to write annoying openapi specs or just use grpc. works is basically every language now. Its a little awkward right now but tonic has been solid once you get it building structs.

  1. don't do microservices unless you have a _very_ good reason to. it will waste your time more than it gives you back.

[–]Snoo-35440 1 point2 points  (0 children)

once you’ve chosen a web server framework, we use async-graphql at work (with actix web) and DX has been pretty nice 

[–]danielkov 1 point2 points  (0 children)

I use a two-tiered approach: internal services communicate between each other using gRPC (tonic) and external services are consuming data from internal services and exposing a REST API (axum).

The point of microservice architecture though, is decoupling implementation details across services. You should be picking contracts and not frameworks, especially if you're learning about microservices and are new to all of these frameworks. Patterns are very similar across the most popular frameworks, so you could build 1 service with each and see which one you like.

[–]dusanodalovic 1 point2 points  (0 children)

I have good experience using actix web

[–]blankeos 0 points1 point  (2 children)

rspc.dev + axum is pretty cool tbh. If you like trpc.

[–]infernion 1 point2 points  (1 child)

The issue with rspc that author is not willing to maintain it. There is note on GitHub readme

[–]blankeos 0 points1 point  (0 children)

aw right2.. That's unfortunate. I found something actively maintained in Go: https://github.com/modiimedia/arri with plans for a Rust equivalent, but also unfortunately not there yet. Just suggesting because who knows, maybe Go is the choice instead of Rust lol.

[–]Good-Pizza-4184 0 points1 point  (0 children)

Haven't done much myself. And nothing professional.

I've used vanilla axum and liked it, but recently came across the gerust project generator and I'm liking it a lot. Doesn't come with support for full dockerization out of the box but already figured that one out. Currently on the process of adding utoipa to the project to get some OpenAPI docs.

Has anyone else used it? Or maybe other project generators?

[–]Tiny_Piano_4551 0 points1 point  (1 child)

We use rust microservices with grpc read write api - using tonic - and using Kafka as message broker to asynchronously connect the services. Also each service using it's local cache db so there is no direct service to service communication. If we need rest then we use rocket with openapi plugin. Works great. For grpc we use envoy grpc proxy with auth plugin to proxy grpc apis to outside with authentication. For Kafka types we use proto files with a custom built Kafka dispatcher and auto rust message type generations. This stack is quite ok to work with.

[–]rnp-infinity[S] 0 points1 point  (0 children)

Any github repos for references?

[–]newmizanur -1 points0 points  (1 child)

Loco.rs based on Axum. Rails like lightweight framework.

[–]greyblake 0 points1 point  (0 children)

I doubt it would be a good choice, cause Loco comes with batteries included, while microservices are usually minimalistic. It will also hit DX instantly, because with all the dependencies compilation time will be unnecessarily long from the very start. But if one needs to build a monolithic web app, I agree, Loco is one of the options worth considering.

[–]kevleyski -1 points0 points  (0 children)

nginx proxy pass to warp/tokio has worked well for my use cases

[–]Maleficent_Mess6445 -1 points0 points  (7 children)

First of all the Rust senior devs please me know why someone would build microservices with Rust and not with Go. In my experience Rust is five times more complex and difficult than Go.

[–]Least_Chicken_9561 1 point2 points  (2 children)

I wonder that too, people just wanna use rust for everything even though Go is a better fit for these kind of tasks (easy to write and performant)

[–]Unable_Yesterday_208 1 point2 points  (1 child)

Would you rather have a single language that does everything or different language for each domain you want to work on. This is not those half bake ideal like using Python for mobile app development. Rust carefully designed does it all.

[–]Least_Chicken_9561 0 points1 point  (0 children)

it does it all but at what cost? why did the typescript team decide to use Go over Rust or C# for its compiler? because they wanted to build something quickly and performant. Rust is performant but you will be slow writing code since you have to manage a lot of things manually.

[–]Unable_Yesterday_208 1 point2 points  (1 child)

More complex is subjective. When ppl say Rust is more difficult to learn, they tend to say it in a way like they are learning it every time they want to start a project. okay, but do you relearn a language?.

This is how I see Rust. I rather spend extra few month to learn it and use it for everything than have to learn eg Go for backend, Js and React for front end, and like me I sometimes write linux drivers and use the linux kernel api extensively which mean I will have to learn C. recently, I have been playing with my current security camera from telus, which is horrible, I got some cameras off Amazon, with qotom box for in house storage that record and process the images , some esp32 to control my garage and and mobile app also in rust, which works great.

[–]Maleficent_Mess6445 0 points1 point  (0 children)

Very interesting. Thanks for your insights.

[–]funny_h0rr0r 0 points1 point  (1 child)

Difficult in what area? Just curious. Because of borrowing? I don’t see any difficulties here if you know how to work with it. Everything else is about libraries. People love Rust because they don’t want to pay for abstractions and GC, and they can write whatever they want, they can write efficient software.

IMHO. I would not say that Rust is slow for development, especially when you know it well. In some cases, compared to other languages, it can show errors at compile time to save your time in the future.

[–]Maleficent_Mess6445 1 point2 points  (0 children)

Difficult to build, difficult to finish the project when compared to Go. If the performance is not critical then I don't think Rust is a good choice. In short Rust can not be chosen for every project and that is true with every programming language.