I · 06

Transports

Part 4 of Z39.88-2004 defines three ways to deliver a ContextObject to a resolver. The one almost everybody uses is called Inline, not By-Value.

A transport is the mechanism that moves a ContextObject from the system that created it to a resolver. Z39.88-2004 defines three OpenURL transports, each registered for HTTP and HTTPS and each usable with GET or POST. All three share the transport keys that begin url_.

TransportWhat travelsRegistry identifiers
InlineThe KEV pairs of one ContextObject, directly in the query stringinfo:ofi/tsp:http:openurl-inline
info:ofi/tsp:https:openurl-inline
By-ValueA whole ContextObject representation as the value of url_ctx_valinfo:ofi/tsp:http:openurl-by-val
info:ofi/tsp:https:openurl-by-val
By-ReferenceThe network location of a ContextObject representation, in url_ctx_refinfo:ofi/tsp:http:openurl-by-ref
info:ofi/tsp:https:openurl-by-ref

Inline

The KEV pairs of exactly one KEV ContextObject are placed directly in the query string, next to the transport keys. This is what nearly every OpenURL in the wild looks like, and the standard notes that it "strongly resembles OpenURL 0.1". Inline can only carry a KEV ContextObject.

https://resolver.example.edu/openurl?
url_ver=Z39.88-2004
&url_ctx_fmt=info:ofi/fmt:kev:mtx:ctx
&ctx_ver=Z39.88-2004
&rft_val_fmt=info:ofi/fmt:kev:mtx:journal
&rft.atitle=An+Article+Title
&rft.jtitle=A+Journal
&rft.date=2020
&rfr_id=info:sid/example.com:database
url_ver
Required. Fixed value Z39.88-2004.
url_tim
Optional. Creation time of the OpenURL.
url_ctx_fmt
Optional for Inline. If present, info:ofi/fmt:kev:mtx:ctx.

Any other key that is neither a url_ key nor a KEV ContextObject key is a foreign key: allowed, but with no meaning defined by the standard. Resolvers may ignore it. Old 0.1 keys such as sid or genre in a hybrid OpenURL are foreign keys from a 1.0 point of view.

By-Value

The complete ContextObject representation becomes the value of a single key, url_ctx_val, and url_ctx_fmt says which ContextObject Format it uses. Because a KEV ContextObject is already URL-encoded and is then encoded again as a value, its contents end up double-encoded (%3A becomes %253A). The same ContextObject as above, By-Value over GET:

https://resolver.example.edu/openurl?url_ver=Z39.88-2004
&url_ctx_fmt=info%3Aofi%2Ffmt%3Akev%3Amtx%3Actx
&url_ctx_val=ctx_ver%3DZ39.88-2004%26rft_val_fmt%3Dinfo%253Aofi%252Ffmt%253Akev%253Amtx%253Ajournal%26rft_id%3Dinfo%253Adoi%252F10.1103%252FPhysRev.47.777%26rft.jtitle%3DPhysical%2BReview%26rft.date%3D1935
url_ver
Required.
url_ctx_fmt
Required. info:ofi/fmt:kev:mtx:ctx or info:ofi/fmt:xml:xsd:ctx.
url_ctx_val
Required. The ContextObject representation itself.

By-Value can carry an XML ContextObject too, which is why SAP2 uses it. It is rare in ordinary linking.

By-Reference

The ContextObject representation is stored at a network location and the OpenURL carries only that location. The resolver fetches it before processing. This suits large XML ContextObjects or bundles of several ContextObjects.

https://resolver.example.edu/openurl?
url_ver=Z39.88-2004
&url_ctx_fmt=info:ofi/fmt:xml:xsd:ctx
&url_ctx_ref=https://source.example.com/contextobjects/12345.xml
url_ver
Required.
url_ctx_fmt
Required.
url_ctx_ref
Required. The URL of the ContextObject representation.

Do not confuse. The By-Reference transport (url_ctx_ref) is different from By-Reference metadata for one Entity (rft_ref_fmt + rft_ref), which lives inside a ContextObject and can travel in any transport. Likewise, "by value" is often used loosely for Inline OpenURLs; in the standard's terms they are Inline.

GET or POST

With GET, the KEV pairs form the query string after the resolver's base URL. With POST, the same string is sent as the message body with Content-Type: application/x-www-form-urlencoded. POST avoids URL-length limits; GET is what a clickable link uses.

URL length

Appendix E of the standard sets no maximum length, but says resolvers must accept OpenURLs of at least 255 bytes after encoding and should accept at least 2048 bytes. Long author lists or abstracts can exceed what some proxies and browsers handle; POST or By-Reference avoid the problem.

Where COinS fits

COinS is not a transport defined by Z39.88-2004. It is a community convention for embedding a KEV ContextObject in an HTML <span>. Client-side software later turns it into an Inline OpenURL to the user's resolver.

Choosing a transport

  • Use Inline over GET for links from databases, catalogues and reference lists. Include url_ver=Z39.88-2004 and ctx_ver=Z39.88-2004.
  • Use Inline over POST or By-Reference when the ContextObject is too large for a URL.
  • Use By-Value or By-Reference when sending XML ContextObjects.

Sources