4 ms·
One thing I wish was covered in these is how to go past 'hello world', especially things like error responses and serialization models. It took me a while befor
by status_quo69 7y ago
One thing I wish was covered in these is how to go past 'hello world', especially things like error responses and serialization models. It took me a while before I got to the point where I think I can be productive in both querying the data from the front-end and getting back the shape that I wanted. Couple of lessons learned:
- Start with separating your API models and DB models out early, you'll be thankful later. You can also help yourself out by implementing From/Into for your database models to your API models. Obvious lesson from CQRS but since rust doesn't allow easily for ad-hoc structs this is a must, especially since there are a lot of examples out there that put a Serialize/Deserialize onto the database object.
- If you have deeply nested objects, look into JSON:API or Juniper. There are a couple of crates that implement the jsonapi spec and I'm hacking on one of them to make it a bit more usable for my personal pet project, but Juniper will make your life easier especially if you're starting with a React frontend.
- Understand that there's still a tracking issue for a few items such as multipart data, although there's a third party crate that integrates the multipart crate into rocket. However if you need an upload you could probably get away with just returning a signed S3 endpoint to the user, which is what I ended up doing
- If integrating with redis or some other database that's not application critical, there is no (as far as I'm aware) graceful degredation that comes out of the box with rocket_contrib, unless there was some config value I was missing. This is usually fine, since you can easily declare an ad-hoc fairing that connects to redis and falls back to an Option::None in the case where it couldn't connect.
And finally, if you want to support different error status codes yourself based off of mappings from internal errors (such as 409 conflict when inserting the same data), your best bet is an enum that's wrapped by a responder derive like so:
#[derive(Responder, Debug)]
pub enum UserApiError {
#[response(status = 500, content_type = "json")]
Unavailable(Json<UserApiErrorMessage>),
}
impl UserApiError {
fn wrap_body(message: &str) -> Json<UserApiErrorMessage> {
Json(UserApiErrorMessage {
status: "error".to_string(),
message: message.to_string(),
})
}
pub fn unavailable(message: &str) -> Self {
Self::Unavailable(Self::wrap_body(message))
}
}
Which can be called like:
Err(UserApiError::unavailable("The database is gone!"))
Most of my other lessons learned come from diesel, both are an absolute pleasure to work with and have given me incredible confidence while coding.
- sandGorgon 7y agoThis is awesome. Is there a resource for someone just beginning with rust (but with many years on flask and rails).
- status_quo69 7y agoThe best way to learn rust depends on your learning style, the Book (https://doc.rust-lang.org/book/index.html https://doc.rust-lang.org/book/index.html) is fantastic even as a reference. To learn rocket I'd start with the official tutorial here: https://rocket.rs/v0.4/guide/getting-started/#getting-started https://rocket.rs/v0.4/guide/getting-started/#getting-starte... It might sound canned, but the rust community generally has fantastic documentation and the few edge cases you'll hit are generally well-known in the github issues with well-known causes. My advice would be that if you feel like the compiler is giving you too much grief, take a break for a day or two and then come back to it, you might find that what was giving you trouble isn't so bad anymore. The compiler is very helpful with error messages but because of the litany of information that it gives you it can become a bit of a brain overload, especially if you hit a particularly nasty diesel type error (compile time SQL is no joke!) It's also good to know in advance that the rust standard lib is great, but fairly bare bones if you want things like JSON support. Check out https://www.arewewebyet.org/ https://www.arewewebyet.org/ for the tools that can help you out! EDIT: The only other thing that I just thought of is that authz/authn doesn't have a good story in rust just yet, so I'd rely on an external service of some kind to handle that for you unless you want to do basic signed session cookies.
- sandGorgon 7y agothanks for this - but i already know a bit of rust. That's why your previous post was so awesome. it was a rough path to get to a production ready api/web front. For example, i would tell an Android beginner - "use coroutines. use Retrofit. dont use MVVM, but use ViewModels. Dagger is a big pain, but Koin can break in production", etc.
- status_quo69 7y ago