carllerche / tower-web

A fast, boilerplate free, web framework for Rust
MIT License
980 stars 51 forks source link

Vec and Option do not implement Response #146

Closed real-felix closed 5 years ago

real-felix commented 5 years ago

I am doing a very small API with something like that:

#[derive(Debug, Clone, Serialize, Response)]
struct Foo {
    value: String,
}

struct Controller {
    mocked_db: HashMap<u64, Foo>,
}

impl_web! {
    impl Controller {
        #[get("/values")]
        #[content_type("application/json")]
        fn values(&self) -> Vec<Foo> {
            self.mocked_db.iter().map(|(_id, value)| value.clone()).collect()
        }

        #[get("/values/:id")]
        #[content_type("application/json")]
        fn one_value(&self, id: u64) -> Option<Foo> {
            self.mocked_db.get(id).map(Clone::clone)
        }
    }
}

This is a very common usecase, but I could not find any example of this (maybe I've looked in the wrong place).

In this situation, it feels natural to return a Vec for a JSON array and an Option where there could be or not a result (in this case, None would be a 404 error).

I solved the first case by using the newtype pattern:

#[derive(Debug, Serialize, Response)]
struct MyFoos(Vec<Foo>);

In the case of optional return, if I understand well, I must return an Either type with either a 404 status or the wanted Foo, but I feel that this boilerplate is unnecessary.

Do you think that it is possible to implement Response:

?

carllerche commented 5 years ago

I think that is good 👍