4

Let's say I have a reverse proxy set up getting traffic at http://gluten-free-snacks.example.com. It serves different URLs by sub-directories, not sub-domains, for a better web UX.

Its default behavior is to route all requests to a WordPress site which I handed over to the marketing team which they will definitely use to create some social media buzz and generate leads. No questions there. The reverse proxy's additional behavior is that all requests to http://gluten-free-snacks.example.com/my-account/* get routed to a separate server running a small CRUD app. It's running express.js, or not if you'd prefer.

Should I write this app to serve requests from / (or ./, in another sense) and have the proxy hide from it the fact it's publicly available at /my-account/?

From / (agnostic about its URL and directory), the code seems more self-contained and easy to refactor, and we've separated out what seems to be a networking detail. However, all its HTML links to static assets like /stylesheets/main.css are now broken, because they're actually available at /my-account/stylesheets.main.css. In fact, all its links need to become relative, which hurts refactorability.

Should I:

  • Make the app serve from / and use relative paths for links?
  • Host static assets elsewhere?
  • Make the app serve from /my-account/ and use absolute paths for links?
  • Do something different because this is an XY problem?

Multiple answers may apply.

3
  • Why are you talking about microservices in the title, while your question is exclusively about two web apps which are neither microservices, nor even ordinary services? Jan 4 '17 at 19:55
  • The word "microservices" has a broad enough definition that I think its usage in the title was appropriate. I gave an example involving two web apps so answers can have an example to work with, but my question is not primarily about the two web apps in the example.
    – Eric
    Jan 4 '17 at 21:32
  • Not really. A microservice is a web service which is a part of a solution which has a very specific componentization architecture. For what it's worth, Wikipedia could give an overview of the term, although the article is not particularly detailed nor concrete. I'll edit your question to focus on web apps aspect. Jan 4 '17 at 21:40
6

The app should be URL-agnostic, for the simple reason that it is not unusual:

A web page contains three types of URLs:

  • URLs relative to the actual page.

    Example: main.css

  • URLs relative to the root, that is the domain name.

    Example: /index.html

  • Absolute URLs.

    Example: https://ajax.googleapis.com/ajax/libs/jquery/3.1.0/jquery.min.js

An application which is hosted at https://example.com/app1 can point to a relative URL such as <link href="main.css"> which would lead to https://example.com/app1/main.css, to URLs relative to the root, such as <a href="/"> which would lead to https://example.com/, and to absolute URLs such as <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.0/jquery.min.js"></script>.

In all three cases, the actual location of the application doesn't matter: it can be hosted as https://example.com/app1, https://app1.example.com, https://cdn.example.com/oregon/app1/, etc. As soon as the resources relative to the page stay within the app, and the resources relative to the root stay at the root, the app will work.

The problem, however, is when you start using URLs relative to the root in the cases where they are not expected—and this is exactly the situation with static resources. There are two types of static resources:

  • Common static resources can be used by multiple applications.

    In this case, you'd better put them in a CDN and reference them through an absolute URL such as https://s.example.com/something/here/global.css. It doesn't matter if it is a public CDN such as Amazon CloudFront, or something your company hosts and which may not even be technically a CDN; the only thing that matters is that URLs would be absolute, which gives you the flexibility of being able to use them independently of the actual URL of the application.

  • Application-oriented resources are used exclusively by the application. They are never shared with other web apps.

    Here, you can still move them to a CDN (if it's an actual CDN, it will also give you the benefit of better performance and lower impact on your app servers).

    If, however, you decide to keep them together with the app (for instance because your favorite framework does the minification and the bundling on the fly), then use URLs relative to the actual page, not the domain. This way, you'll know that it will work no matter how you access your app, would it be https://example.com/, https://app1.example.com/, https://example.com/app1 or https://123.45.67.89/.

For the rare cases where CDN is overly complex to use, and the static resources are shared among several apps, you may solve the problem with a simple URL rewriting. When a page hosted at https://example.com/app1/index.html will point to https://example.com/app1/main.css, the URI will be redirected automatically to, for instance, https://example.com/static/main.css.

Note that accessing the same static resource through multiple URIs won't do any good to client-side caching, so URL rewriting should be reserved only to cases where CDN is actually difficult to use. Another solution is to use redirects. Here, you get the benefits of client-side caching, at the cost of an extra HTTP request.

1

Generally, I would say "no, it doesn't need to be aware of ITS URL"

For the example you mention, I would distinguish the URL for the microservice, versus the URL for the resources it may embed. For example, if it will link to images and styles, I would suggest the microservice receives the base URLs for them as separate parameters.

2
  • Thanks for answering both the broad and the specific questions. Do I understand correctly that you're suggesting static assets be hosted elsewhere? Also, would the microservice get the base URLs for static assets via configuration parameters, service discovery, or can it vary based on what works best for the system?
    – Eric
    Jan 4 '17 at 19:14
  • Not necessarily, there are valid reasons to host static assets on the same place. But parameterizing the location allow for both in-place hosting or moving them out, for example to a CDN. As you say, where to save configuration is a separate problem, and it depends on what works best for the system; some systems prefer configuration files, other to keep such configuration in databases, among many other options (and most big systems, a mix of them, not always a nice mix). Jan 4 '17 at 22:45

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.