Considerations for NENA Working Groups in Designing Web Services for Maximum Consistency: Difference between revisions

Undo revision 6765 by MikeVislocky (talk) Removed test word.
(Added NENA REF number and changed ref to citation.)
(Undo revision 6765 by MikeVislocky (talk) Removed test word.)
Tag: Undo
 
(13 intermediate revisions by 2 users not shown)
Line 1:
 
NENA-REF-008.1-2020
 
'''©''' Copyright 2020 National Emergency Number Association, Inc.
 
NENA DS-Interface Specification Development WG<ref>[https://dev.nena.org/communities/community-home?CommunityKey=041f8444-7e41-423f-94b7-4ad0f00acb5a NENA DS-Interface Specification Development WG]</ref>
Line 10 ⟶ 13:
 
== Introduction ==
Standards commonly include functionality performed by cooperating entities using a defined interface. For example, NENA i3 specifies a logging function where various elements generate log events that are created and stored by a logging server, and entities are able to retrieve log events from the logging service.   In general, such functionality is specified using a network protocol (which allows the entities to be located on the same machine, on different machines, even on different machines in different networks, and to be provided by different vendors). Designers of such protocols may choose to create a new protocol for their purpose (which might be an entirely new protocol or a modification of an existing protocol) or to re-use an existing protocol.  When a protocol is reused, the standard specifies how the information for the functionality is conveyed using the existing protocol.  Various models are possible, although often such services use a concept of a request and a response, and often the side making a request is referred to as the client, and the side receiving the request and sending a response is referred to as the server.  Protocols may be directional (one side initiates requests and the other side responds) or not (either side may send data to the other at any time), and may be synchronous or asynchronous.  In synchronous protocols, messages are only sent at defined instances, for example, in synchronous client/server protocols, servers only send messages to clients in response to a request; in some protocols, each response can only result in one response.  Asynchronous protocols allow messages to be sent at any time or for multiple responses to be sent to a single request.  For example, an HTTP<ref>[2https://tools.ietf.org/html/RFC7230 RFC7230 Hypertext Transfer Protocol (HTTP)]</ref> server sends one response to each request; a SIP<ref>[3https://tools.ietf.org/html/rfc3261 RFC3261 Session Initiation Protocol (SIP)]</ref> server may send intermediate responses before sending a final response to an initial request, and once a SIP session has been established, either side may send messages to the other at any time; XMPP<ref>[4https://tools.ietf.org/html/rfc6120 RFC6120 Extensible Messaging and Presence Protocol (XMPP)]</ref> was explicitly designed to allow endpoints to send messages to other endpoints at any time.
 
In recent years, a common choice for service designers has been to use HTTP over TLS<ref>[5https://tools.ietf.org/html/rfc5264 RFC5264 Transport Layer Security (TLS)]</ref> (referred to as HTTPS), with data needed for the functionality conveyed as XML or JSON<ref>[6https://tools.ietf.org/html/rfc8259 RFC8259 The JavaScript Object Notation (JSON) Data Interchange Format]</ref> objects in the request and response messages. One reason this is often the choice is the wide availability of and familiarity with tools that handle HTTP over TLS with XML<ref>[7http://www.w3.org/TR/2008/REC-xml-20081126 Extensible Markup Language (XML), World Wide Web Consortium, Recommendation REC-xml-20081126, November 2008]</ref> or JSON objects.  Such tools allow for automating aspects of the implementation.  When such functionality uses HTTP, it is referred to as a web service (that is, a service implemented using web protocols and techniques), and the web service can be described as being layered on top of HTTP.
 
NENA work groups (WGs) that design web services typically need to decide how various aspects of the interfaces function.  Certain important aspects are described below.
Line 59 ⟶ 62:
1.    Request parameters may be passed in the URL. There are two mechanisms for this:
 
a.    The parameters (often identifiers), as values (or sometimes as names and values), may be components of the path.  E.g., the following URL operates on the “widgets” resource with the identifier “3”; the identifier parameter is a component of the path:<syntaxhighlight lang="html">
<nowiki>https://foo.example.org/interface/widgets/3</nowiki>
 
</syntaxhighlight>b.    The parameter may appear at the end of the path, delineated by a question mark or semicolon, e.g., in the following URL, the parameter name (“widgetID”) and value (“3”) are passed using “?” syntax:<syntaxhighlight lang="html">
<nowiki>https://foo.example.org/interface/widgets/3</nowiki>
<nowiki>https://foo.example.org/interface/widgets?widgetID=3</nowiki>
 
</syntaxhighlight><nowiki>https://foo.example.org/interface/widgets?widgetID=3</nowiki>
b.    The parameter may appear at the end of the path, delineated by a question mark or semicolon, e.g., in the following URL, the parameter name (“widgetID”) and value (“3”) are passed using “?” syntax:
 
<nowiki>https://foo.example.org/interface/widgets?widgetID=3</nowiki>
 
2.    Parameters may be encoded as HTTP header fields of requests or responses, e.g., the following example HTTP request fragment contains (at the end) a header field “Web-Service-widgetID” with a value of “3”:
 
2.    Parameters may be encoded as HTTP header fields of requests or responses, e.g., the following example HTTP request fragment contains (at the end) a header field “Web-Service-widgetID” with a value of “3”:<syntaxhighlight lang="html">
GET / HTTP/1.1
 
Host: foo.example.org
 
User-Agent: WizzBang CPE Magic 43
 
Accept: application/json
 
Accept-Language: en-us,en;q=0.5
 
Accept-Encoding: gzip,deflate
 
Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7
 
Web-Service-widgetID: 3
</syntaxhighlight>3.    Parameters may be encoded within a body part of a request or response.
 
HTTP messages consist of a header, containing fields, and optionally, a body consisting of a MIME<ref>[8https://tools.ietf.org/html/rfc2046 RFC2046 Multipurpose Internet Mail Extensions (MIME)]</ref> type.  A MIME type may be multipart, containing one or more child MIME parts. The term “body part” is typically used to refer to any of these MIME type elements, even when the body is a single MIME type.
3.    Parameters may be encoded within a body part of a request or response.
 
HTTP messages consist of a header, containing fields, and optionally, a body consisting of a MIME[8] type.  A MIME type may be multipart, containing one or more child MIME parts. The term “body part” is typically used to refer to any of these MIME type elements, even when the body is a single MIME type.
 
When encoding parameters within a body part (method 3), virtually any MIME type could be used to contain the parameters.  For example, a web service could use a “text/plain” body part, defining a text-based syntax for encoding parameters, or could use a “multipart/form-data” or “application/x-www-form-urlencoded” body part as if sending HTML <form> data. A web service could create and register its own MIME type, with parameters structured using JSON, XML, or any other format.  Since web services typically make use of JSON or XML object encoding, parameters are most commonly passed as one or more JSON or XML objects, i.e., as one or more body parts of “application/json”, “text/xml”, “application/xml”, or one of the many more specific MIME types with a subtype containing “+json” or “+xml” (indicating JSON or XML encoding).
 
Note that passing a body in a GET “has no defined semantics,<ref>[9https://tools.ietf.org/html/rfc7231 RFC7231 Hypertext Transfer Protocol (HTTP/1.1): Semantics and Content]</ref>” although some tools and systems support it. Since NENA web services operate within the constrained context of NENA-defined systems, doing so is less of a concern than it would be with the web in general, where endpoints and intermediate systems (such as proxies) might not support it.
 
The URL (method 1) and header field (method 2) mechanisms are primarily suitable for scalar values (such as strings, numbers, and Booleans), as opposed to complex objects (such as arrays).  While complex objects could be encoded into header fields, in practice, the most reasonable solution is to encode them as an object in the body (such as a JSON or XML object).
Line 99 ⟶ 91:
For the HTTP header field mechanism (method 2), the use of “X-“ header fields is common, but discouraged by the IETF.
 
Identifiers can be considered a special case. The REST[10]<ref>Representational state transfer (REST), a style in which HTTP usage is constrained in certain ways, to optimize and simplify the use of HTTP.  There is no single, authoritative definition of REST, but it is generally agreed that it entails a model in which HTTP verbs are used to act on resources.</ref> style encourages a conceptual model in which operations are performed on resources; when there is a simple identifier for a resource, making it an element of the path is a common approach that facilitates using the HTTP verbs in what are generally considered appropriate ways (i.e., GET to retrieve, POST to create, PUT to update, and DELETE to delete). When complex or sizeable parameters need to be passed in addition to an identifier, there will be a data object in the HTTP request body anyway, so passing the identifier in the path means that most parameters are in the body while some are in the path, which can needlessly complicate the mechanism. When only simple parameters are needed, the use of path elements plus URL question mark and semicolon parameters is an option (subject to URL length and encoding constraints).
 
==== Guidance: ====
Line 113 ⟶ 105:
2.   PUT
 
3.   PATCH<ref>[https://tools.ietf.org/html/rfc5789 RFC5785 “PATCH Method for HTTP”]</ref>
3.   PATCH[11]
 
4.   DELETE
Line 123 ⟶ 115:
The amount of time that elapses from when a server receives a request until it transmits the response will of course vary depending on multiple factors, including server load or stress, resource storage (e.g., local versus remote database, database type, etc.).  In general, operations that access or retrieve data tend to be overall quicker than operations that write data, although server-specific conditions are typically more significant.  Network conditions and intermediate systems obviously can affect round-trip times.  Some interface designs accommodate the possibility that some operations might take an extended amount of time by allowing for polling or call-backs.  When invoking an interface that does not support polling or call-backs, client implementations must wait for a response or until a maximum wait time (timeout) is reached.  Typically, clients either:
 
·*        Transmit a request and wait for a reply or a timeout, with a timeout treated as an error, or
·*        Transmit an operation and perform other tasks while waiting for a reply, with a timeout treated as an error.
 
·        Transmit an operation and perform other tasks while waiting for a reply, with a timeout treated as an error.
 
The former is sometimes termed “blocking” or “hanging” on a response.  The latter may be implemented as a main processing loop that invokes code for various events that may occur, one of which is receiving a response to a previously sent request.
Line 214 ⟶ 205:
1.    A header field specifies what version is supported.  Often this is the ''Accept'' header field but sometimes a custom header field is used.  This is the same as passing the version as a parameter using the HTTP header as described in Option 2 of Section 2 (Request and Response Parameters).
 
2.    The version is specified in the path.  The following example requests the resource “Policies” of version “v1.3” of the “PolicyStore” service of an API provided by the host “services.example.com”:<syntaxhighlight lang="html">
<nowiki>https://service.example.com/PolicyStore/v1.3/Policies</nowiki>
 
</syntaxhighlight>3.    A version entry point is included in the API for the service or server.  A client performs a GET on this entry point and receives a list of versions supported at the server.  For example, a GET on the URL '' <nowikisyntaxhighlight lang="html">https://service.example.com/PolicyStore/Versions</nowiki>'' might return ''“1.0, 1.5, 2.0, 3.0”''.
<nowiki>https://service.example.com/PolicyStore/v1.3/Policies</nowiki>
https://service.example.com/PolicyStore/Versions
 
</syntaxhighlight>might return ''“1.0, 1.5, 2.0, 3.0”''.
3.    A version entry point is included in the API for the service or server.  A client performs a GET on this entry point and receives a list of versions supported at the server.  For example, a GET on the URL ''<nowiki>https://service.example.com/PolicyStore/Versions</nowiki>'' might return ''“1.0, 1.5, 2.0, 3.0”''.
 
The “versions” entry point can be defined per server or per service. Defining “versions” as per server implies a simpler set of web services where it is expected that an individual server implementation will monolithically support all entry points for all services.  Defining a “versions” entry point for each service allows more complex situations where a server build supports different versions per service.  As an example, a vendor might have a major release that supports version 6 of all services, then in a subsequent point release update one service to version 7, etc., as a means of getting support for later versions into deployment faster.  Defining “versions” as per service means that even though the same server can provide multiple services, clients must send a request to the “versions” entry point of each service before using the service; version information is allowed to differ between services.  Either way, it’s important to note that version information might change between requests, as a server could fail-over or be upgraded in between requests.
Line 224 ⟶ 215:
4.    A service discovery mechanism has version information in it.
 
5.   New endpoints are defined with new names when non-backwards compatible changes are introduced.  For example, the service<syntaxhighlight ''api.example.com/PolicyStore/Policies'' might be deprecated in favor of the new service ''api.example.com/PolicyStore/ManagePolicies''.lang="html">
api.example.com/PolicyStore/Policies
 
</syntaxhighlight>might be deprecated in favor of the new service <syntaxhighlight lang="html">
Note that the header field mechanism (item 1) typically specifies what is supported at the client, while the others usually specify what is supported at the server. When the query doesn’t have non-backwards-compatible extensions, the header approach allows any client to construct a query that is acceptable for any server where there is at least one common version, and the server can determine from the header what version response the client can accept.
api.example.com/PolicyStore/ManagePolicies
</syntaxhighlight>Note that the header field mechanism (item 1) typically specifies what is supported at the client, while the others usually specify what is supported at the server. When the query doesn’t have non-backwards-compatible extensions, the header approach allows any client to construct a query that is acceptable for any server where there is at least one common version, and the server can determine from the header what version response the client can accept.
 
The path mechanism (item 2) allows the client to specify the version it is using, but unless one of the other server version mechanisms are available to inform the client which versions are supported at the server, the client has to guess, potentially requesting an unsupported version, receiving an error that the URL doesn’t exist, trying another URL with a different version, and so on.
Line 238 ⟶ 231:
 
==== Description: ====
As mentioned in the Introduction and elsewhere, software development commonly uses tools to automate some of the code development, verification, or other aspects.  A number of tools have been designed for HTTP protocols, which (as mentioned in the Introduction) is one reason HTTP is often chosen as the layer on which to build services.  When designing a service, especially a web service, one consideration may be the degree of compatibility of the design with common tools.  For example, service designers might choose to define their services using an OpenAPI<ref>[12https://www.openapis.org OpenAPI]</ref><ref name=":0">[https://swagger.io Swagger]</ref> format, to be suitable as input into various tools.
 
==== Guidance: ====
For maximum consistency among NENA web services, use the Swagger Hub tool, which supports Open API. NENA has a limited license for this tool; contact the NENA Technical Issues Director for access.  Consult the i3 Policy Store and Logging web services for examples of how to structure the YAML file (which defines the web service) to maximize consistency.  Also note that the swagger.io[13]<ref name=":0" /> tool is available for free and can be used to develop and validate the correctness of an API.
<br />
----[1] <nowiki>https://dev.nena.org/communities/community-home?CommunityKey=041f8444-7e41-423f-94b7-4ad0f00acb5a</nowiki>
 
[2] Hypertext Transfer Protocol (HTTP), <nowiki>RFC 7230</nowiki>, <nowiki>https://tools.ietf.org/html/rfc7230</nowiki>.
 
[3] Session Initiation Protocol (SIP), <nowiki>RFC 3261</nowiki>, <nowiki>https://tools.ietf.org/html/rfc3261</nowiki>.
 
[4] Extensible Messaging and Presence Protocol (XMPP), <nowiki>RFC 6120</nowiki>, <nowiki>https://tools.ietf.org/html/rfc6120</nowiki>.
 
[5] Transport Layer Security (TLS), <nowiki>RFC 5246</nowiki>, <nowiki>https://tools.ietf.org/html/rfc5246</nowiki>.
 
[6] The JavaScript Object Notation (JSON) Data Interchange Format, <nowiki>RFC 8259</nowiki>, <nowiki>https://tools.ietf.org/html/rfc8259</nowiki>.
 
[7] Extensible Markup Language (XML), World Wide Web Consortium, Recommendation REC-xml-20081126, November 2008, <nowiki>http://www.w3.org/TR/2008/REC-xml-20081126</nowiki>.
 
[8] Multipurpose Internet Mail Extensions (MIME), <nowiki>RFC 2046</nowiki>, <nowiki>https://tools.ietf.org/html/rfc2046</nowiki>.
 
[9] Hypertext Transfer Protocol (HTTP/1.1): Semantics and Content, <nowiki>RFC 7231</nowiki>, <nowiki>https://tools.ietf.org/html/rfc7231</nowiki>.
 
[10] Representational state transfer (REST), a style in which HTTP usage is constrained in certain ways, to optimize and simplify the use of HTTP. There is no single, authoritative definition of REST, but it is generally agreed that it entails a model in which HTTP verbs are used to act on resources.
 
[11] “PATCH Method for HTTP”, <nowiki>RFC 5789</nowiki>, <nowiki>https://tools.ietf.org/html/rfc5789</nowiki>
 
[12] <nowiki>https://www.openapis.org</nowiki>, <nowiki>https://swagger.io</nowiki>, etc.
 
== References ==
[13] <nowiki>https://editor.swagger.io/</nowiki>
<references />
[[Category:Technical Guides]]
[[Category:Article]]
[[Category:NENA Reference]]