-1

I'm building a front end that interfaces with a 3rd party API, and my question is regarding the proper pattern to use with that third party API.

My existing code isn't very sophisticated, and I find that I'm writing the same code over and over again.

 var httpClient = //dependency injection here
 var response = await httpClient.GetAsync($"{httpClient.BaseAddress}/Web/Session/{_sessionKey}");

 if (!response.IsSuccessStatusCode)
 {
    //throw exception
 }
    var result = await response.Content.ReadAsStringAsync();
    var model = SessionModel.FromJson(result);

What's different from one response to the next is that it could be a POST, and/or the endpoint, with possibly different parameters. And of course the JSON objects that are returned also depend on what was sent. There is a 1-1 correspondence of endpoint to the JSON object getting returned (which I would then convert to a model).

I've looked around to see how to handle this in terms of a pattern, but most of what I find is directions and advice if you are the API server, not the API consumer. I did find this, but it's not exactly asking the same question, though the answer it gives is a bit closer to what I'm looking for.

So, is there an API consumer pattern that deals with sending a GET/POST, handles different endpoints and parameters, checks the response for validity/errors and returns a proper error response, and/or converts the (non-error) JSON to the appropriate model?

Thanks!

  • 2
    Does this answer your question? Choosing the right Design Pattern – Bart van Ingen Schenau Jun 12 at 7:09
  • 1
    One comes to mind. Templating. – Laiv Jun 12 at 8:05
  • No - it doesn't answer my question because I'm not looking for a pattern simply for the sake of using one; rather, I'm looking for one to relieve myself of the pain of writing the same code over and over. And because it can make for better code. – NovaDev Jun 12 at 12:17
  • 1
    I'm not sure what you're looking for is a "design pattern" so much as a tool or abstraction. Consider taking the solution you created and posting it on The Code Review Stack Exchange so that you can get feedback and see if there's anything you missed. – TheRubberDuck Jun 16 at 14:23
4

Software engineering isn't about going in a book of design patterns, finding the one which matches the thing you're trying to do and blindly copying it. Just write good code and the patterns you need to use will become obvious. This answer expresses it better than I can here.

Given all that, how would I approach this?

What's different from one response to the next is that it could be a POST

OK, so that's easy. Just pass in a parameter to your function which determines whether to call HttpClient.GetAsync or HttpClient.PostAsync. If you want more flexibility, pass in a IHttpClient => HttpResponseMessage callback.

and/or the endpoint, with possibly different parameters.

Again, pass in a callback to create the URI for you.

And of course the JSON objects that are returned also depend on what was sent.

So make your function generic on a type T and pass in a callback of type (string => T) to make your model.

If you don't like callbacks, replace each of them with an appropriate interface and pass in a object which implements that interface.

There is a 1-1 correspondence of endpoint to the JSON object getting returned (which I would then convert to a model).

So sounds like you can wrap your three callbacks up into an interface of some form:

interface IEndpointProcessor<T>
{
  Uri GetUri(...);
  HttpResponseMessage CallApi(IHttpClient httpClient);
  T CreateModel(string json);
}

Create a class which implements that interface for every endpoint you have and then have a collection of those. And at this point, you can go into your book of design patterns and find out which ones you've used, but it doesn't really matter that much.

| improve this answer | |
  • Thank you. Your first comment helped me a lot. As did your link, though the link gave me more context without necessarily answering the question I had. Basically what I get out of this is sometimes you need to create your own pattern. :-) – NovaDev Jun 12 at 12:21
0

I thought I'd post my own solution to wrap this up.

I created a RestService class with a Get method, Post method, and Put method, then I pass in the URL with its parameters, and the object for the Post and Put methods. The Post and Put just take the generic type for the object.

Then, if I get a bad response, I can throw the exception right there. Otherwise I know I'm getting good data back, so I can convert the JSON to the expected model.

I'm really happy with this solution, since it puts the same code I'm using over and over in one place. I should have realized that I was doing it the wrong way sooner.

var result = _restService.Post("CRM/WebLogins", constituentInfo);

And then my Post method signature. The rest of the method looks like the code I posted above.

public async Task<string> Post<T>(string url, T model)

So the solution wasn't a pattern after all, just smarter use of code, and the realization not to write the same thing over and over. I just couldn't figure out how to do it until I wrote my question, and got a great answer.

| improve this answer | |

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.