Resource Identifier Syntax (and Resources)
Resource identifiers represent the actual resources that a service exposes. A resource can be data, processing logic, files, or anything else that a service may have access to. A resource identifier is like a unique ID assigned to one or more service resources.
It's important to understand that a uniform contract does not standardize resource identifiers. It standardizes the syntax used to express them. The most common syntax used to express resource identifiers is the Web's Uniform Resource Identifier (URI) syntax.
Before we continue exploring resource identifiers, let's briefly cover some of the URI basics. (If you are already familiar with URI syntax, then skip ahead to the Resource Identifiers and REST Services section.)
URIs (and URLs and URNs)
The Uniform Resource Identifier (URI) standard is defined by the IETF, and provides a syntax that includes a list of allowed and prohibited characters, a generic structure for identifiers, and further defines the concepts of Uniform Resource Locators (URLs) and Uniform Resource Names (URNs). The relationship between URIs, URLs, and URNs is highlighted in Figure 1.
Figure 1 - How URIs, URLs and URNs relate to each other.
- URIs are simply sequences of characters that conform to the standardized syntax.
- URLs are URIs that can be used in requests. Referring to concepts in a way that can be used directly as a resource to send messages to its underlying service is so useful that most URIs used in REST service architectures are also URLs. This makes the terms somewhat equivalent, which is the reason they are often used interchangeably.
- URNs are URIs that can be used as unique identifiers for resources, such as business entities. Many identifiers in REST are URIs, URLs, and URNs at the same time.
For example http://invoices.example.com/invoice/INV042 is a URI because it conforms to the generic syntax. It is also a URL because we can use it as a resource identifier and invoke methods upon it. Finally, it is a URN because we will always refer to the invoice using this identifier outside of the Invoice service itself. This combination of URI, URL, and URN work together to ensure that the discovery of resources, and the ability to access the data they refer to, usually occur at the same time.
The generic syntax for URIs is as follows:
This syntax can be extended to form a URI reference by adding a fragment component:
The different elements of the syntax denote the beginning or end of each component, and whether the component is present or not:
- the colon ":" after scheme indicates the presence of the scheme
- the double-slash "//" before authority indicates an authority is present
- path is always present, and generally begins with a slash "/"
- query is denoted by a leading question mark "?"
- fragment is denoted by a leading hash symbol "#"
An example URI reference that uses all of these components is:
- http is the scheme, denoting the use of the Hypertext Transfer Protocol for URLs
- invoices.example.com is the authority
- /invoices is the path
- total-less-than=100USD is the query
- page2 is the fragment component
Resource Identifiers and REST Services
Each resource identifier can be service-specific, and one REST service can provide many resource identifiers for use by its service consumers.
Because REST services can have a functional context and scope, the same way other kinds of services can, a given REST service can be based on a service model. This means a REST service can be agnostic or non-agnostic - and - business-centric or utility-centric. The REST service's functional context carries over into the types of resources it encapsulates, which in turn determines the types resource identifiers we define for a REST service.
For example, we could have an entity REST service called Customer. This service would be responsible for encapsulating agnostic, customer-related resources. A resource identifier we could create to provide the ability for the Customer service to retrieve data about a specific customer record might look something like this:
In this example, the C081 part of the URL represents the customer record ID provided by the service consumer requesting specific customer data, while the http://customer.example.com/ part of the URL represents the Customer service itself.