First project code review

I would not recommend creating a separate method for each endpoint/request. That's not extensible and requires a lot of boilerplate (as evidenced by e.g. your json_ok!() macro), making the code hostile to refactoring.

I instead suggest you follow how I usually wrap HTTP APIs. The TL;DR is:

  • Represent requests and responses using types

  • Make these types implement common Request and Response traits that allow you to convert between strong, Rust-native types and weak, HTTP-native types. Hopefully, this should be as easy as adding Serialize/Deserialize as supertrait bouds and deriving the traits for your request/response model types.

  • Request should have the Response as an associated type

  • The client should have exactly one method for sending a request, with the approximate signature of:

    fn send<R>(&self, request: R) -> Result<R::Response, MyApiError>
    where
        R: Request;
    
3 Likes