Search code examples
restsingle-page-applicationhateoas

SPA Routing with a RESTful API using HATEOAS


When using routing in a SPA web app (angular, react, etc), the user doesn't have to start at the entry point of the application. They can use a URL in the browser to drill down into any part of the application.

When implementing HATEOAS in a RESTful backend API, we assume that the front-end only knows the URL to the entry point of the API, and then the API provides links to other parts of the application from there.

So this begs the question, if a user enters a URL in the browser that loads a specific part of the SPA (not the entry point), how does the SPA get the appropriate API link needed for just that part of the SPA?

Does the SPA just make a bunch of API calls all at once, starting at the entry point of the API and following links until it gets the link it needs for the state it needs to load? And what happens when the API does not include the link needed because it's not a valid link based on the current state of the application?

HATEOAS doesn't seem to be very compatible with a modern SPA where you can load the application at very specific sections/states.


Solution

  • This has been asked on SO before, but I'm having trouble finding these past questions and answers. I've answered at least two, but I'll summarize how this usually gets answered.

    Camp 1: Don't do SPA's, it doesn't make sense. Your HATEOAS service should serve the entire state in a way that the client can interpret and SPA's are basically a hack.

    Camp 2 (the camp I'm in): You'll need some way to map SPA links to links on your backend.

    You're kind of describing this by talking about 'all the steps needed' to get to the right resource, but if your goal it ultimately map this to an API uri, why not embed just that

    https://spa.example/http://api.example/some/resource
    

    Having bookmarkable urls that contain the full path to your backend, means you don't need to jump through complex hoops, and your SPA is a true client for the API you are building.

    Another nice benefit is that you can also easily point your client to multiple live/dev environments.

    Lastly, you could allow for relative urls and automatically resolve them to the API url, shortening:

    https://spa.example/http://api.example/some/resource
    

    to

    https://spa.example/some/resource