Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

HATEOAS through an HTML representation #2579

Open
steve-chavez opened this issue Nov 30, 2022 · 9 comments
Open

HATEOAS through an HTML representation #2579

steve-chavez opened this issue Nov 30, 2022 · 9 comments
Labels
idea Needs of discussion to become an enhancement, not ready for implementation

Comments

@steve-chavez
Copy link
Member

steve-chavez commented Nov 30, 2022

Problem

REST is defined by four interface constraints: identification of resources; manipulation of resources through representations; self-descriptive messages; and, hypermedia as the engine of application state.
https://www.ics.uci.edu/~fielding/pubs/dissertation/rest_arch_style.htm#sec_5_1_5

We're still missing the HATEOAS constraint. We usually get criticism on HN for not complying to it.

Previously HATEOAS was discussed from the point of view of adding JSON-LD/HAL representations for our responses, from which there's no clear benefit - they don't ensure a universal client as they need their own libraries(see json-ld clients, hal clients) for users to interact with them.

In contrast, HTML in the browser has the right affordances built-in as discussed on the following articles:

Proposal

Enable HATEOAS by providing an HTML representation at the root endpoint as an alternative to OpenAPI.

In practical terms, this would provide a powerful admin interface for us.

It could list all our resources(relations collections with their relationships + functions) and provide links to their different representations. Some browsers even support JSON and CSV views, which would make this great as a data visualization tool.

To even have more fidelity to the original hypertext idea(better illustrated by Ted Nelson's Xanadu), we could implement something similar to wikipedia page previews.

@steve-chavez steve-chavez added the idea Needs of discussion to become an enhancement, not ready for implementation label Nov 30, 2022
@steve-chavez steve-chavez changed the title HATEOAS as an HTML representation HATEOAS through an HTML representation Nov 30, 2022
@docteurklein
Copy link

Glad to see the idea discussed 👍

Indeed one big standing issue for the "glory of rest" is the client support (there is a whole chapter about that in Mike Amundsen's hypermedia book "RESTful Web APIs" I think).

For what it's worth, I used to work on a universal client for many formats (including html) in as many languages as possible: https://github.com/hippiemedia.

It's great to see HTML discussed here, but once you started implementing this, you'll realize there is no conceptual reason (except browser support, but that's arbitrary) to not support json-ld and similar formats like vnd.siren or hal+hal-forms (although hal is getting old).

On the contrary, HTML is the only one who mixes concerns with the presentation layer, thus creating friction with what to include in the responses (unless you only plan the same admin interface every time).

Still I think it's a great idea and started exploring it myself using rust https://github.com/docteurklein/httpg.

A difficulty I see is the support for POST-Redirect-GET patterns and what happens for forms that don't validate (they should be redisplayed in the POST response with errors attached, but currently postgREST is more a 400+204 kind of guy)

@steve-chavez
Copy link
Member Author

Mike Amundsen's hypermedia book "RESTful Web APIs" I think

I think it's this one: RESTful Web Clients. Gave it a look and I see it discusses HAL and Siren.

A difficulty I see is the support for POST-Redirect-GET patterns

Looks like that pattern is not needed with ajax and htmx(SO link).

It's great to see HTML discussed here, but once you started implementing this, you'll realize there is no conceptual reason (except browser support, but that's arbitrary) to not support json-ld and similar formats like vnd.siren or hal+hal-forms

Yeah, this will be more experimental than anything, lots of things could change.

Still I think it's a great idea and started exploring it myself using rust https://github.com/docteurklein/httpg.
why ?
Because postgREST is painful to work with as soon as you want something else than JSON,

Cool! I do agree and I did want to bring better support for other media types on #1582, but that stagnated. Meanwhile most users kept asking for more JSON-related features.

@kephas
Copy link

kephas commented Feb 16, 2023

Previously HATEOAS was discussed from the point of view of adding JSON-LD/HAL representations for our responses, from which there's no clear benefit - they don't ensure a universal client

This is not the intended benefit of HATEOAS. The main reason for HATEOAS being a core constraint of the REST style is decoupling.

When your client only knows one or a very small number of entry points and every other URL is retrieved through hypermedia controls, it means you can freely change how your organize routes in your server without changing the client. The URLs stop being part of the API, apart from the entry points.

An interesting question could then be: why us PostgREST named that way if it doesn't follow the REST architecture? That may not be a bad thing. The intent of this project is to expose SQL tables through an HTTP API. So maybe REST isn't relevant here.

@steve-chavez
Copy link
Member Author

When your client only knows one or a very small number of entry points and every other URL is retrieved through hypermedia controls, it means you can freely change how your organize routes in your server without changing the client. The URLs stop being part of the API, apart from the entry points.

Yeah, this is exactly what we want to do with an HTML representation, not with custom JS clients that are not really universal - hence no real decoupling as per what you mention above.

An interesting question could then be: why us PostgREST named that way if it doesn't follow the REST architecture?

With the exception of HATEOAS, we do follow all the REST constraints and we even have plans to implement the Code on demand "optional constraint". To put it in more constructive terms, we can always improve our REST compliance instead of having a naming discussion.

(IMO, if our name were such a desecration on REST, then I don't think we'd have had Roy Fielding trying to help us before)

@kephas
Copy link

kephas commented Mar 29, 2023

With the exception of HATEOAS, we do follow all the REST constraints

It is a pretty big exception.

Quoting Roy Fieldings's PhD thesis where he defines REST, in section 5.1.5:

REST is defined by four interface constraints: identification of resources; manipulation of resources through representations; self-descriptive messages; and, hypermedia as the engine of application state.

He reiterated the fact several years later: "REST APIs must be hypertext-driven".

Is there a reason why you follow all REST constraints but HATEOAS? Why not let the client be cleanly decoupled from the server's implementation?

@steve-chavez
Copy link
Member Author

Why not let the client be cleanly decoupled from the server's implementation?

Hm, how would you do that specifically? What format would you expect as a response? Which endpoints should work?

@kephas
Copy link

kephas commented Mar 30, 2023

I guess I would have a single entry point with the / route that would contain something like:

{ "tables":
  { "users":  { "list": "/users", "filter": "/users" } }
}

(which means that if I want to use the name=Joe feature of PostgREST, I know to use the filter URI; hich is the same now as the one to get the full content of the table)

This doesn't look very useful as of now, but it means that if you discover that it would be better to implement the full listing of a table and the filtering in different routes, now you can and people don't need to change their clients. You can also add new features easily, again without worrying about clients in the wild. Your new version will pretty much automatically be backwards compatible.

@steve-chavez
Copy link
Member Author

I guess I would have a single entry point with the / route that would contain something like:

{ "tables":
  { "users":  { "list": "/users", "filter": "/users" } }
}

Your new version will pretty much automatically be backwards compatible.

Interesting! So which libraries can consume that format at the root endpoint? I assume they follow a standard format.

@kephas
Copy link

kephas commented Apr 1, 2023

You can take a look at traverson for a REST API client that's geared towards HATEOAS.

There isn't one standard format for REST, no. REST is an architectural style, not a protocol. But there are a few standards for REST APIs if you want to follow one. Hydra is an example, it's in the JSON-LD ecosystem.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
idea Needs of discussion to become an enhancement, not ready for implementation
Development

No branches or pull requests

3 participants