9

A team at the office is developing web micro-services intended to support sales sites and mobile apps with total combined orders count of less than 100K (not sure how much less but greater than 10K) per month.

They are using NodeJS, Docker and AWS. Their idea is that each service will only have one or two endpoints and its own DB.

For example there would be a Tax service that only GETs the tax calculated for an Order object, then another PlaceOrder service receives a POST with an Order object, possibly another CheckStatus service would return current status for an Order object or ID etc.

Each of these services is actually a completely separate NodeJS project, hosted in a separate repo, compiled by a separate Jenkins project and put in its own Docker container, which is then deployed on a server of its own (Beanstalk)

Each of these servers then gets a domain name for each of its deployment phases (DEV, QA, INT, STAGE, PROD), so for the two services we have in the example there are 10 domain names: PHASE.taxService.api.company.com and PHASE.orderService.api.company.com

Question is: is this a normal practice, do you see benefits or issues with this scenario. Is there a reason to prefer either dev.taxService.api.company.com or dev.company.com/api/taxService?

4
  • Do these services need to be hosted on the same machine? You would lose a lot of scalability doing so.
    – Matthew
    Commented Mar 21, 2015 at 5:43
  • They don't have to be on the same machine. Scalability isn't an issue for most of them as the throughput is low (<100K/month), for others it may be an issue. The purchasing services would all have to call the same (slow) integration middleware, which in turn calls into the same (slow) SAP back-end Commented Mar 21, 2015 at 18:41
  • The question is mostly about the format of the URL, I haven't seen another company use the domain name, it's always the same domain name with a path after it Commented Mar 21, 2015 at 18:42
  • Really interesting question. Have you decided on a concept yet? I'd really like to know your reasoning. I have a similar question here: stackoverflow.com/questions/50728484/…. My problem with subdomains is that I'd have to differentiate the health check routes anyway. I havent come to a conclusion yet, though.
    – Michael
    Commented Jun 7, 2018 at 6:46

3 Answers 3

9

Update: this is an old answer that implies HTTP/1.1. For HTTP/2 the logic is more or less the same except multiplexing, if supported by both ends, allows to have one TCP connection per host.


This is an interesting and important question, I'm surprised it hasn't gotten much attention.

In addition to @thexacre's response, you need to consider your client's behavior and how it may choose to reuse connections. From the client's perspective a host is a single entity that can serve requests to various paths within one HTTP connection (the Keep-alive feature). The keep-alive timeout can be e.g. one minute but it can be configured on the client side and negotiated with the server. The second factor is the client's maximum number of simultaneous connections, also configurable but usually limited to save resources.

Having said that, you need to look at how often each of your endpoints will be called by the client and whether the client will benefit from HTTP connection reuse. The one host + multiple paths strategy seems to be more convenient from the client's perspective, because it may choose to fire multiple requests simultaneously, or to serialize them depending on whether it wants to save local resources (memory and CPU) or to retrieve data as fast as possible.

On the other hand, if a client has to deal with many host names it means it will create separate HTTP connections with each one of them; connection reuse will be impossible.

Then there's the server side. If you are running a microservice architecture it means for a one-host strategy you will need to have a request router, a potential bottleneck. It is more convenient from the server's perspective to have separate host names for logically isolated endpoint groups: you will have a flexibility of choosing an architecture (microservice vs. monolithic), changing the architecture later, migration as mentioned in the other answer, potentially no need for a router, etc.

All in all, I would say if the client can potentially make a great number of requests within a limited amount of time, and if it is important to handle them efficiently on the client side then the client will benefit from fewer host names, ideally just one. However, if the client makes only a few requests at a time then consider what's best for your service, and that would more likely be multiple host names.

2
  • Excellent point, one I had not considered Commented Jun 7, 2018 at 18:57
  • If an endpoint is serving images to browser clients, this would be the way to go yes? For the simple matter of caching 500kb files?
    – pspahn
    Commented Jun 29, 2019 at 0:57
10

Is there a reason to prefer either dev.taxService.api.company.com or dev.company.com/api/taxService?

It seems basically your question boils down to whether it's better to use sub-domains or sub-directories to separate services.

It seems there's plenty of people on either side of the fence, for example:

Google seems to prefer sub-directories, here's two examples of different services:

Amazon seems to prefer sub-domains, for example:

Personally I generally prefer sub-domains because:

  • They don't require a load balancer / reverse proxy to map the sub-directory to a service.
  • Sub-directories make sense in the context of HTTP, but if your service involves other protocols then it may not.
  • It's usually easier to split services between infrastructure providers using sub-domains which is useful during a migration. ie. you can easily move service 1 to provider B by pointing the sub-domain there, while service 2 remains on provider A. Doing that with a sub-directory will probably require you to reverse proxy to a totally separate data centre.
2
  • It seems to me in the Amazon case SQS and S3 are completely independent APIs, rather than different endpoints that actually talk to same backend. I do see your point that it's easier to split/migrate. Commented Mar 22, 2015 at 3:31
  • 1
    @StenPetrov well if taxService is the only service you have then it won't really matter because the host-name will be dedicated to that service either way (even if the root of that service is located in a sub-directory). If you introduce postageService for example though then you'll have multiple services with independent APIs like SQS vs. S3.
    – thexacre
    Commented Mar 22, 2015 at 3:53
1

Your question is how should you separate your services: via DNS or via HTTP.

DNS

  • Does not require a shared load balancer. Traffic goes directly to that service's infrastructure.

  • No complexity of path/subpath translations.

HTTP

  • Clients can re-use connections, improving latency especially for TLS (HTTPS).

  • Fewer DNS records and TLS certificates/names to manage.


For me, it's a matter of how independent the services are.

Is this "one API"? Or "several APIs"?

To me, it sounds like your microservices are all part of the same logical API/application, even if you have implemented them as different processes. So in that particular case, I would separate phases by DNS and microservices by HTTP.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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