8

For context, I am running a REST API built with Node.js. Because of callbacks and some complex DB calls, I have a chain of functions that are async but also unique, so it's tough to reduce redundancy. I came up with the idea to call my own endpoints (different endpoints) from within the code itself so I can reduce redundancy. Is this bad practice?

For instance, I would have:

app.get("/puppies/:id"...)  // Simple get by ID endpoint

app.post("/puppies"...)  // Simple puppy update, but checks an attribute of puppy first by getting by ID

In the post endpoint, it would be nice to simply call the "get" endpoint within the post code, but it feels dirty. Thoughts?

1
  • 2
    This is like the web equivalent of photocopying a smartphone screen. Why so indirect? You can bypass the entire HTTP layer, and just call the underlying puppy_update function or whatever
    – Alexander
    Nov 15 '20 at 5:43
17
  1. There is little use of actually doing an HTTP request.

    When the underlying application processes the GET request from your example, it probably calls the business layer which does some input checking, and then calls the data access layer which retrieves the puppy.

    In a similar way, the POST request could, instead of doing an additional GET, simply ask the business layer to update the puppy; the business layer, in turn, will start by calling the data access layer method which retrieves the corresponding puppy.

  2. Doing an extra HTTP request will, however, have several drawbacks.

    • There would be a performance cost. For instance, you'll sanitize inputs twice, while doing it once is enough. Creating HTTP context and processing it has a cost as well; it's not huge, but why adding it when you can avoid it so easily?

    • It makes your application more complicated that it should be. Why would you do an HTTP request, while the data you need is just in front of you (i.e. in the data access layer interface)?

      And I'm not even mentioning all the extra code you'll need. For instance, how you will configure the URI of the service to call? Will it be put in configuration (if yes, what would happen if the service moves), or will it be generated on the fly (in which case, how long it will take you to find the right solution, which will handle ports, relative URIs, HTTP/HTTPS, etc.?)

    • It will add an extra line to your app server logs. And the logs of the reverse proxies.

    • It will make the code more difficult to refactor. For instance, with the solution where the business layer calls the data access layer's method which retrieves a puppy, it's quite natural to think about moving the logic down the layer—in data access layer in a form of a query, or maybe the database itself. On the other hand, when you do an HTTP request, it completely abstracts away the logic behind the GET request, making it impossible to optimize later.

5
  • Thanks for such a detailed reply! I'll consider this as I move forward with my project.
    – DonutGaz
    Apr 2 '17 at 5:42
  • 1
    Does it make sense to use API calls if we need to make use of the load balancer for the same API?
    – John
    Dec 26 '19 at 19:17
  • There's also a chance of deadlock, depending on the web server.
    – user253751
    Nov 16 '20 at 17:16
  • There's also the chance of any kind of networkish failure - or delay - (even on the same machine) that you'd get with any RPC.
    – davidbak
    Nov 16 '20 at 20:28
  • To highlight on @John's question which I am also curious about. If the API is running on multiple instances behind a load balancer, and let's say the endpoint triggers a computationally expensive call. Would there be any benefit to calling its own endpoint to distribute the load across multiple instances of the API?
    – portatlas
    May 25 at 18:19
5

Yes its bad(tm).

The extra overhead of making the http call although needless probably wont be much of a factor.

I think The real dangers are:

  • The accidental introduction of endless loops. ie Post calls get and Get calls Post or similar scenarios.

  • Unindented caching effects

  • http server issues, maximum requests on the server etc

  • Threading issues, when you make the call and wait for it to be processed async

Basically a lot of bits and bobs that don't break your code, but definitely introduce issues you would rather not have to worry about.

In any case your code should be structured in such a way that it is easy to make the get call, or part of it directly. without hitting the http layer. It sounds like you haven't put your code into a business layer

-1

I'm not an expert by any means with Node, but why don't endpoint call function. By decoupling the code from the endpoints, I would think that the function can be called from multiple endpoints without the need to make a request.

Let me know if that sounds stupid.

-1

No it is not bad, just do it wisely. I mean, there is no point for calling one controller from another, it breaks SOLID. But you can add additional layer of UseCases (as in Clean Architecture) and Services. There should be clear advantage of calling one use case from another or to calling few use cases from one service.

Edit: Original answer below: Wordpress allows it in it's Rest API framework. It is called "internal request" and it's purpose is to ease making batch requests (as in your example). Method used to make internal requests accepts Request object, not an url. Just read the article, it will give you an idea how You could code it in Your solution.

PS: If u want to downvote just tell me in the comments why

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