Library

Browse and search developer information

GS1 Server

By Connecting for Health | 6 March 2013

Introduction

The NHS is making increasing use of barcodes in a number of areas. Particularly, they are used:

  • Nationally to identify:
    • patients notes and, during hospital stays, patients themselves, using a wristband;
    • blood transfusions
  • Locally, to identify:
    • locations (eg this is ward 10)
    • medical samples
    • assets (eg ultrasound scanners)
    • disposable items, such as forceps or returnable gas cylinders

GS1 is an international organisation that manages barcodes:

  • how they are printed and formatted
  • how they are interpreted as data
  • how they map to registries of companies and organisations

GS1’s registries cover many areas, but the most useful are:

  • The GS1 company prefix. This is a prefix at the start of a barcode that identifies a company and its issuing agency
  • The GS1 issuing agency – which is nearly always national or supra-national. This is usually the same as the country of residence of the organisation. Its identifier is the GS1 prefix.

This scheme of numbers and registries ensures that any organisation’s barcodes are unique and don’t impinge any other organisation. In addition, it means that an organisation can create and assign its own barcodes, with no need to consult or use a central authority. In this scheme, a barcode comes to be an unique number – similar perhaps to a Type 1 UUID or an Ethernet MAC. As a consequence:

  • GS1 can’t easily tell you to whom a barcode belongs
  • Barcodes don’t generally encode data (there are rare exceptions, eg for ISBNs)
  • There is no central way of taking a barcode and finding out details of the item it represents

A further complexity is that the GS1 company prefixes vary in length – a bit like credit card number prefixes.

All this can make finding information about barcodes hard.

Finding information – the HDN GS1 Web Service

To make it easier to find out information about the range of barcodes in use in the NHS, the GS1 Web Service has been written. It’s a simple REST interface with an endpoint at http://services.developer-test.nhs.uk/gs1/organisation/.

The service provides ways to either:

  • Find all the NHS organisations using GS1 barcodes, their address details and their GS1 Company Prefix
  • Find a particular organisation given a barcode. This is a single record, but with the same details.

There is also support for getting results in different formats.

For convenience, there’s also a java client that wraps up using the REST API.

The REST API

Endpoint

The relative path to the REST service endpoint is /gs1/organisation/. The public, production endpoint is at http://services.developer-test.nhs.uk/gs1/organisation/. This is hosted on Azure and does not support the use of ping (and other ICMP operations) to determine service availability.

HTTP Version

The endpoint supports using HTTP/1.0 and HTTP/1.1. HTTP/1.1 is preferred, but support for HTTP/1.0 exists so that the endpoint can remain compatible with common CDNs (Content Delivery Networks) such as AmazonCDN and caches (such as Squid or Varnish).

HTTP Methods (Verbs)

All methods allow the use of GET, HEAD and OPTIONS. The latter is provided to allow the use of pre-flighted queries by browsers supporting the W3C’s naive cross-origin request framework.

HTTP Request Headers Overview

The endpoint doesn’t require the use any particularly special HTTP request headers. It is good practice to supply Host, User-Agent and Accept headers. The value of Accept is ignored and content-type is determined using the query string (see below). This is a technical violation of the HTTP spec but is done to maximise compatibility with the vast numbers of naive clients (including browsers) in use.

The If-Modified-Since and If-Unmodified-Since headers are supported, allowing the effective use of caching. ETags are not used.

HTTP Response Headers

The server will always specify the Content-Type and provide a Content-Length. Transfer-Encoding is consequently not chunked and not specified. Support for compression (Content-Encoding) is not supported but may be transparently added in the future.

The server adds Cross-Orgin-* headers allowing use in browsers implementing these naive W3C policies.

Additional headers are added to prevent use by robots, to overcome weaknesses in IE and to support future use over HTTPS.

If the OPTIONS header is specified then an Allow header is returned with a comma and whitespace separate string of supported HTTP methods for the resource.

Return Codes

Queries using GET and HEAD will return either 200 OK or 404 Not Found. Queries using OPTIONS will return 204 No Content.

Character Sets (charset)

All text results use the UTF-8 charset without exception. An ‘UTF-8 BOM’ (sic) does not precede the data.

Resources

All Organisations

Relative URL HTTP Method Results as Try It! Notes
/gs1/organisation/ OPTIONS List of Headers with Allow Header curl -v -X OPTIONS http://services.developer-test.nhs.uk/gs1/organisation/
/gs1/organisation/ HEAD List of Headers curl --head http://services.developer-test.nhs.uk/gs1/organisation/
/gs1/organisation/ GET JSON http://services.developer-test.nhs.uk/gs1/organisation/
/gs1/organisation/?format=xml OPTIONS List of Headers with Allow Header curl -v -X OPTIONS http://services.developer-test.nhs.uk/gs1/organisation/?format=xml
/gs1/organisation/?format=xml HEAD List of Headers curl --head http://services.developer-test.nhs.uk/gs1/organisation/?format=xml
/gs1/organisation/?format=xml GET XML http://services.developer-test.nhs.uk/gs1/organisation/?format=xml
/gs1/organisation/?format=csv OPTIONS List of Headers with Allow Header curl -v -X OPTIONS http://services.developer-test.nhs.uk/gs1/organisation/?format=csv
/gs1/organisation/?format=csv HEAD List of Headers curl --head http://services.developer-test.nhs.uk/gs1/organisation/?format=csv
/gs1/organisation/?format=csv GET CSV http://services.developer-test.nhs.uk/gs1/organisation/?format=csv Always includes a header row
/gs1/organisation/?format=tsv OPTIONS List of Headers with Allow Header curl -v -X OPTIONS http://services.developer-test.nhs.uk/gs1/organisation/?format=tsv
/gs1/organisation/?format=tsv HEAD List of Headers curl --head http://services.developer-test.nhs.uk/gs1/organisation/?format=tsv
/gs1/organisation/?format=tsv GET TSV http://services.developer-test.nhs.uk/gs1/organisation/?format=tsv Always includes a header row
/gs1/organisation/?format=json&callback=FUNCTION OPTIONS List of Headers with Allow Header curl --head http://services.developer-test.nhs.uk/gs1/organisation/?format=json&callback=FUNCTION
/gs1/organisation/?format=json&callback=FUNCTION HEAD List of Headers curl -v -X OPTIONS http://services.developer-test.nhs.uk/gs1/organisation/?format=json&callback=FUNCTION
/gs1/organisation/?format=json&callback=FUNCTION GET JSONP http://services.developer-test.nhs.uk/gs1/organisation/?format=json&callback=FUNCTION FUNCTION should be replaced by an appropriate callback name

Search

To search for an organisation using a barcode, append the barcode to the relative URL. For example, for the barcode 5055220798768, http://services.developer-test.nhs.uk/gs1/organisation/5055220798768 will find the organisation. Results are returned in the same formats as for all organisations. For the JSON and XML formats, this is the same list structure – but with just one element. This makes parsing simpler. In the tables below, replace BARCODE with a barcode that is either a GTIN-12 (12 digits 0 – 9), GTIN-13 (13 digits 0 – 9) or a GTIN-14 (14 digits 0 – 9). The service validates that the barcode is correctly formatted.

If a match is not found or the barcode is invalid, the service will return 404 Not Found.

Relative URL HTTP Method Results as Try It! Notes
/gs1/organisation/BARCODE OPTIONS List of Headers with Allow Header curl -v -X OPTIONS http://services.developer-test.nhs.uk/gs1/organisation/5055220798768
/gs1/organisation/BARCODE HEAD List of Headers curl --head http://services.developer-test.nhs.uk/gs1/organisation/5055220798768
/gs1/organisation/BARCODE GET JSON http://services.developer-test.nhs.uk/gs1/organisation/5055220798768
/gs1/organisation/BARCODE?format=xml OPTIONS List of Headers with Allow Header curl -v -X OPTIONS http://services.developer-test.nhs.uk/gs1/organisation/5055220798768?format=xml
/gs1/organisation/BARCODE?format=xml HEAD List of Headers curl --head http://services.developer-test.nhs.uk/gs1/organisation/5055220798768?format=xml
/gs1/organisation/BARCODE?format=xml GET XML http://services.developer-test.nhs.uk/gs1/organisation/5055220798768?format=xml
/gs1/organisation/BARCODE?format=csv OPTIONS List of Headers with Allow Header curl -v -X OPTIONS http://services.developer-test.nhs.uk/gs1/organisation/5055220798768?format=csv
/gs1/organisation/BARCODE?format=csv HEAD List of Headers curl --head http://services.developer-test.nhs.uk/gs1/organisation/5055220798768?format=csv
/gs1/organisation/BARCODE?format=csv GET CSV http://services.developer-test.nhs.uk/gs1/organisation/5055220798768?format=csv Always includes a header row
/gs1/organisation/BARCODE?format=tsv OPTIONS List of Headers with Allow Header curl -v -X OPTIONS http://services.developer-test.nhs.uk/gs1/organisation/5055220798768?format=tsv
/gs1/organisation/BARCODE?format=tsv HEAD List of Headers curl --head http://services.developer-test.nhs.uk/gs1/organisation/5055220798768?format=tsv
/gs1/organisation/BARCODE?format=tsv GET TSV http://services.developer-test.nhs.uk/gs1/organisation/5055220798768?format=tsv Always includes a header row
/gs1/organisation/BARCODE?format=json&callback=FUNCTION OPTIONS List of Headers with Allow Header curl --head http://services.developer-test.nhs.uk/gs1/organisation/5055220798768?format=json&callback=FUNCTION
/gs1/organisation/BARCODE?format=json&callback=FUNCTION HEAD List of Headers curl -v -X OPTIONS http://services.developer-test.nhs.uk/gs1/organisation/5055220798768?format=json&callback=FUNCTION
/gs1/organisation/BARCODE?format=json&callback=FUNCTION GET JSONP http://services.developer-test.nhs.uk/gs1/organisation/5055220798768?format=json&callback=FUNCTION FUNCTION should be replaced by an appropriate callback name

Running the Server

If you’re curious, you can run your own copy of the server.

The web service is written in java, but is not a war and does not need a legacy container technology like Jetty or Tomcat. Wars, containers and the java servlet spec really are a technology of the past. Instead, it uses the built in Java 6+ web server (which uses NIO, FYI, and is a pretty clean implementation), with an abstraction layer (common-http-server-sun) to provide proper REST semantics.

The web service is open source. The server is such that it can be used either as a Debian/Ubuntu package from our hosted apt repository at http://services.developer-test.nhs.uk/repositories/apt/hdn/, with integrations for logging, upstart, firewalls and a reverse proxy, or as a standalone java library (jar). You can also fork the code from github.

If you’ve installed the deb package

If you’ve installed using the apt repository, then the server is started automatically. It will also start automatically on boot once the network is available. It is controlled using upstart, the Ubuntu replacement for SysV init.d. The upstart job is called hdn-gs1-server and its configuration file is /etc/init/hdn-gs1-server.conf. To stop the server, run stop hdn-gs1-server. To start it, run start hdn-gs1-server. To find out if it is running, run status hdn-gs1-server.

Default settings for binding, ports and the like are controlled using /etc/default/hdn-gs1-server (which specifies a profile to use) and /etc/hdn-gs1-server/profiles/ordinary. The upstart job uses this ordinary profile. Additionally, environment variables can be used to control debugging and java functionality. Some example settings for remote debugging and visualvm (using jstatd) are in the profile /etc/hdn-gs1-server/profiles/debug. Examine the file /usr/sbin/hdn-gs1-server to see other environment variables and how they are used. Firewall settings are in sub folders under /etc/hdn-firewall/. Heap size is controlled by /etc/hdn-gs1-server/heap-size.

If using the standalone java program

You can run the program as:


java -jar hdn-gs1-server.jar ...

Where … are options.

Checking it all works

To find out more, we can ask for help:


java -jar hdn-gs1-server.jar --help

which tells us what’s possible:

Option                                  Description
------                                  -----------
--backlog <Integer: TCP connection      (default: 20)
  backlog>
--data-path <File: Folder path          (default: /srv/hdn-gs1-server)
  containing data to server>
--domain-name <domain name to list on>  (default: developer-test.nhs.uk)
--help                                  Displays help for options
--http-port <Integer: port to listen    (default: 7000)
  for HTTP on>
--version                               Displays version

You may wish to adjust these as needed by your set up. The server should support binding on IPv6 if an IPv6 host is specified. However, it has been designed to be used behind a reverse proxy and this is unlikely to be useful IPv6 is not supported on Azure, our current development platform.

Checking the version installed

Let’s run java -jar hdn-gs1-server.jar –version:

hdn-gs1-server 2013.03.01.1537-development
© Crown Copyright 2013

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

Written by Raphael Cohn (raphael.cohn@stormmq.com)

Standard GNU-like stuff. It’s worth understanding the version number, in this case, 2013.03.01.1537-development. The part before the hyphen is the timestamp of the last git check in used to build the binary – you should be able to find it using git log. Additionally, this should match the version of the deb package. The part after is the git branch the code was built from. Usually this will be either development or master.

If instead it says unknown version then it means you’re using code you’ve compiled yourself or wasn’t released ‘officially’.

Changing the data used by the Server

If you’re running the server, you can change the data it serves if new information is available.

The data served by the server is in /srv/hdn-gs1-server/gs1-company-prefixes.tsv. This a tab separated value (TSV) file. The order of the columns is significant. The server uses a file watch on this file, so, as soon as it changes, the new file is parsed and served. There is no need to restart the server. If for some reason it can not be parsed, then the server will continue to serve its previous copy. If this happens, examine the file. Writing a new copy will cause the server to attempt to use and serve it – there is never a need to restart the server.

If you’re changing this file, it is important to check it into github at (as of writing) source/barcodes/barcodes-gs1-server-application/gs1-company-prefixes.tsv. This ensures that any new build and packaging will include it.