Hacker News new | ask | show | jobs
by fzilla 3566 days ago
REST is just a representation of the underlying data. What does it matter if "status" is a database field or not?

More specifically, it shouldn't have to matter to consumers. Because of the way REST and HTTP work, clients intuitively understand retrieving and modifying resources (via GET, POST, PUT, PATCH and DELETE). But they don't understand interacting with special-purpose endpoints (POST always implies "make a new thing" so it's weird in this context).

Your consumers should not have to learn weird idiosyncrasies in your API because you let your data model bleed into the interface.

2 comments

No, REST and HTTP are implementation details of the technology.

An API is a representation of business workflows and processes. The more accurately you describe or map those to the real world processes, the better your and your consumers' understanding will be.

What if 'status' isn't a column in the account database? What if closed_accounts is a join table or something else? Then wouldn't adding a /close route be hiding idiosyncrasies in your data model, not the other way around?

It seems like we spend a lot of time designing object relations that map a domain, but maybe not so much mapping domain-specific actions.

Or would you consider all of the above bad practice?

This doesn't really matter. What you'll end up exposing via your API is your use case! Does your system allow for an account to be closed? Awesome! So let the client know how to do it.

If you're speaking HTML it can be as simple as:

  <form action="/close-account?acc_number=12345" method="POST">
    <button>Close Account</button>
  </form>
Or even:

  <form action="/close-account" method="POST">
    <input type="hidden" name="acc_number" value="12345">
    <button>Close Account</button>
  </form>
If you're speaking Siren (https://github.com/kevinswiber/siren):

  {
    "actions": [
      {
        "title": "Close Account",
        "method": "POST",
        "href": "/close-account",
        "type": "application/x-www-form-urlencoded",
        "fields": [
          { "name": "acc_number", "type": "hidden", "value": "12345" }
        ]
      }
    ]
  }
> What if 'status' isn't a column in the account database? What if closed_accounts is a join table or something else? Then wouldn't adding a /close route be hiding idiosyncrasies in your data model, not the other way around?

So what? REST is an API [0]. It's the public interface you expose. What you do behind the scene in your data model is, or should be, irrelevant to the API. Sometimes you'll map your data model practically one-to-one to the REST API, but there are times when I do significant logic in controllers before mapping the result of that logic to a resource. As long as the API is resource oriented and follows good REST practices, it's all good.

0. OK, REST is one way to expose an API, since the wording I used is not amenable to some people.

> REST is an API.

No, REST is an architectural style.

> No, REST is an architectural style.

For APIs. But yes, we can argue semantics now. My point is, REST is a way to expose an API.