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
andResponse
traits that allow you to convert between strong, Rust-native types and weak, HTTP-native types. Hopefully, this should be as easy as addingSerialize
/Deserialize
as supertrait bouds and deriving the traits for your request/response model types. -
Request
should have theResponse
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;