REST - What exactly is meant by Uniform Interface?

我们两清 提交于 2019-12-02 16:47:15

Using interfaces to decouple classes from the implementation of their dependencies is a pretty old concept. I am surprised that you haven't heard of it...

By REST you use the same concept to decouple the client from the implementation of the REST service. In order to do define such an interface (contract between the client and the service) you have to use standards. This is because if you want an internet size network of REST services, you have to enforce global concepts, like standards to make them understand each other.

  • Identification of resources - You use the URI (IRI) standard to identify a resource. In this case a resource is a web document.

  • Manipulation of resources through these representations - You use the HTTP standard to describe communication. So for example GET means that you want to retrieve data about the URI identified resource. You can describe an operation with a HTTP method and an URI.

  • Self-descriptive messages - You use standard MIME types and (standard) RDF vocabs to make messages self-descriptive. So the client can find the data by checking the semantics, and it don't have to know the application specific data structure the service uses.

  • Hypermedia as the engine of application state (A.K.A. HATEOAS) - You use hyperlinks and possibly URI templates to decouple the client from the application specific URI structure. You can annotate these hyperlinks with semantics e.g. IANA link relations, so the client will understand what they mean.

The "Uniform interface" constraint, that any ReSTful architecture should comply with, actually means that server responses should announce available actions and resources.

In other words, querying resources should allow the client to request other actions and resources without knowing them in advance.

JSON-API spec offers a good example:

{
  "links": {
    "self": "http://example.com/articles",
    "next": "http://example.com/articles?page[offset]=2",
    "last": "http://example.com/articles?page[offset]=10"
  },
  "data": [{
    "type": "articles",
    "id": "1",
    "attributes": {
      "title": "JSON API paints my bikeshed!"
    },
    "relationships": {
      "author": {
        "links": {
          "self": "http://example.com/articles/1/relationships/author",
          "related": "http://example.com/articles/1/author"
        },
      },
      "comments": {
        "links": {
          "self": "http://example.com/articles/1/relationships/comments",
          "related": "http://example.com/articles/1/comments"
        }
      }
    },
    "links": {
      "self": "http://example.com/articles/1"
    }
  }]
}

Just by analysing this single response, a client knows:

  1. what he was querying (articles)
  2. how are structured articles (id, title, author, comments)
  3. how to retrieve related objects (i.e. author, comments list)
  4. that there are more articles (10, based on current response length and pagination links)

I Hope this helps.
For those passionate about the topic, I strongly recommend reading Thomas Fielding's dissertation!

Chris DaMour

Your question is somewhat broad, you seem to be asking for a restatement of the definitions you have. Are you looking for examples or do you not understand somethings specifically stated.

I agree that the line:

These URI's are going to look like each other

is fundamentally wrong. URIs needn't look anything like each other for the Uniform interface constraint to be met. What needs to be present is a uniform way to discover the URIs that identify the resources. This uniform way is unique to each message type, and there must be some agreed upon format. For example in HTML one document resource links to another via a simple tag:

<a href="URI of related resource" rel="defined relationship">fallback relationship</a>

HTTP servers return html as a text/html resource type which browsers have an agreed upon way of parsing. The anchor tag is the hypermedia control (HATEOAS) that has the unique identifier for the related resource.

The only point that wasn't covered was manipulation. HTML has another awesome example of this, the form tag:

<form action="URI" method="verb">
  <input name=""></input>
</form>

again, browser know how to interpret this meta information to define a representation of the resource acted upon at the URI. Unfortunately HTML only lets you GET and POST for verbs...

more commonly in a JOSN based service, when you retrieve a Person resource, it's easy to manipulate that representation and then PUT or PATCH it right back to it's canonical URL. No pre-existing knowledge of the resource is needed to modify it. Now when we write client code we get all wrapped up with the idea that we do in fact need to know the shape before we consume it...but that really is just to make our parsers efficient and easy. We could make parsers that analyze the semantic meaning of each part of a resource and modify it by interpreting the intent of the modification. IE: a command of make the person 10 years older would parse the resource looking for the age, identify the age, and then add 10 years to that value, then send that resource back to the server. Is it easier to have code that expects the age to be at a JSON path of $.age? absolutely...but it's not specifically necessary.

Ok I think I understand what it means.

From Fieldings dissertation:

The central feature that distinguishes the REST architectural style from other network-based styles is its emphasis on a uniform interface between components (Figure 5-6). By applying the software engineering principle of generality to the component interface, the overall system architecture is simplified and the visibility of interactions is improved.

He's saying that the interface between components must be the same. Ie. between client and server and any intermediaries, all of which are components.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!