Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Example for working with JSON data #351

Open
ghost opened this issue Aug 27, 2019 · 2 comments
Open

Example for working with JSON data #351

ghost opened this issue Aug 27, 2019 · 2 comments

Comments

@ghost
Copy link

ghost commented Aug 27, 2019

Thanks for the hard work on Gotham.

Would it be possible to have an example for how to handle incoming JSON data? I might be missing it if it already exists, if so sorry for the issue.

Context: I am thinking of making a small API using Gotham and would need to accept JSON and then return a JSON response back to the client. I think the latter may be documented though I can't remember where I saw it.

@colinbankier
Copy link
Collaborator

colinbankier commented Aug 27, 2019

Hi @evitalis. Definitely a good idea to include a nice json example.
Here is a pattern I currently use,
I create a helper function to extract the body into any type, for example, given a struct Registration:

fn extract_json<T>(state: &mut State) -> impl Future<Item = T, Error = HandlerError>
where
    T: serde::de::DeserializeOwned,
{
    Body::take_from(state)
        .concat2()
        .map_err(bad_request)
        .and_then(|body| {
            let b = body.to_vec();
            from_utf8(&b)
                .map_err(bad_request)
                .and_then(|s| serde_json::from_str::<T>(s).map_err(bad_request))
        })
}

pub fn register(mut state: State) -> Box<HandlerFuture> {
    let repo = Repo::borrow_from(&state).clone();
    let f = extract_json::<Registration>(&mut state)
        .and_then(|registration| {
            users::insert(repo, registration.user).map_err(|e| e.into_handler_error())
        })
        .then(|result| match result {
            Ok(user) => {
                let body = serde_json::to_string(&user).expect("Failed to serialize user.");
                let res = create_response(&state, StatusCode::OK, mime::APPLICATION_JSON, body);
                future::ok((state, res))
            }
            Err(e) => future::err((state, e.into_handler_error())),
        });
    Box::new(f)
}

I also hope to include such helper functions in gotham itself at some point - for various common request formats.
I've started a full gotham json api with diesel example app over here if that's helpful: https://github.com/colinbankier/realworld-gotham
It's bare-bones and incomplete at the moment - now that we have the 0.4 release out I hope to keep filling it out - but it might give you some ideas in the meantime.

We can keep this issue open to actually include a minimal json example in the gotham examples dir - PRs always welcome!

@ghost
Copy link
Author

ghost commented Aug 28, 2019

@colinbankier Thanks I will try to review this and see how it goes. I was typing on mobile and realized my wording was not great, sorry if it was confusing at all.

When I get a chance to test I will post an update with results. I don't mind doing a PR but not yet that familiar with gotham, and still getting my bearings with Rust, so may not be the best person to submit it.

@msrd0 msrd0 added the example label Aug 27, 2020
@msrd0 msrd0 added this to the 0.6 milestone Sep 11, 2020
@msrd0 msrd0 removed this from the 0.6 milestone Mar 2, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants