jersey-passbook icon indicating copy to clipboard operation
jersey-passbook copied to clipboard

A Java implementation of the Apple Passbook REST API running on Jersey

Build Status

jersey-passbook

jersey-passbook is an example implementation of the Apple Passbook Specification running on Jersey and based on the very excellent Dropwizard framework.

Requirements

  • Java
  • Maven
  • Postgres 9.1 (I like Postgres and I make use of hstore – if you need to replace it with something else, it will require some amount of extra work)

Getting started

To get cracking, check out the project and build a nice fat jar (A single jar file which contains all of the class files required to run the service):

$ mvn package

After that it's off to running the project:

$ java -jar target/jersey-passbook-1.0.jar server service-configuration.yml

There's also a Procfile for foreman, if you prefer that. You can just run:

$ foreman start

For more info on getting up and running with dropwizard projects, check out the comprehensive Dropwizard documentation.

Setup

The database schema is included. jersey-passbook makes use of Liquibase for versioning the database. Further information how this integrates with Dropwizard can be found here.

First, setup the table:

CREATE DATABASE passbook_example;
-- In case you don't have hstore set up yet, run the following command:
CREATE EXTENSION hstore;

Then, to set up the tables, run this from the command line:

$ java -jar target/jersey-passbook-1.0.jar db migrate service-configuration.yml

If you want, you can also insert some test data into the tables to run the examples below:

INSERT INTO passbook_devices (pass_type_identifier, serial_number, authentication_token, data, created_at, updated_at)
                      VALUES ('passTypeIdentifier', 'serialNumber', 'authenticationToken', 'foo=>bar,baz=>bat,xyz=>123'::hstore, current_timestamp, current_timestamp);
                      
INSERT INTO passbook_registrations (device_id, device_library_identifier, push_token, created_at, updated_at)
                            SELECT id,
                                   'deviceLibraryIdentifier',
                                   'pushToken',
                                   current_timestamp,
                                   current_timestamp
                              FROM passbook_devices
                             WHERE pass_type_identifier = 'passTypeIdentifier';

Examples

For details regarding expected response codes please refer to the Apple Passbook Specification.

For testing http calls, I can highly recommend httpie.

Registering a Device to Receive Push Notifications for a Pass

$ http POST http://0.0.0.0:8080/v1/devices/deviceLibraryIdentifier/registrations/passTypeIdentifier/serialNumber pushToken=pushTokenValue HTTP_AUTHORIZATION:"ApplePass authenticationToken"

So here we're registering a device with deviceLibraryIdentifier, passTypeIdentifier and serialNumber. The payload is a JSON dictionary containing:

{
  "pushToken": "pushTokenValue"
}

And finally, there's the HTTP_AUTHORIZATION header which always is set to ApplePass followed by a space followed by the pass’s authorization token as specified in the pass.

Getting the Serial Numbers for Passes Associated with a Device

$ http GET http://0.0.0.0:8080/v1/devices/deviceLibraryIdentifier/registrations/passTypeIdentifier?passesUpdatedSince=tag

If there are matching passes, we'll receive a JSON dictionary with:

{
  "lastUpdated": "timestamp",
  "serialNumbers": [
    "serial1",
    "serial2"
  ]
}

If nothing's found, the service returns status code 204.

There's the optional passesUpdatedSince URL parameter, jersey-passbook would expect a timestamp and filter the result on that timestamp.

Getting the Latest Version of a Pass

$ http GET http://0.0.0.0:8080/v1/passes/passTypeIdentifier/serialNumber HTTP_AUTHORIZATION:"ApplePass authenticationToken"

This call returns the latest version of the requested passs. The response is a JSON dictionary with the pass data. The pass data is stored as hstore so it can basically be anything we want it to be:

{
  "foo": "bar",
  "baz": "bat",
  "xyz": 123
}

The server will also set the proper lastModified value in the response header.

Unregistering a Device

$ http DELETE http://0.0.0.0:8080/v1/deviceLibraryIdentifier/registrations/passTypeIdentifier/serialNumber HTTP_AUTHORIZATION:"ApplePass authenticationToken"

Just returns 200 OK or any other HTTP status code that is appropriate.

Logging Errors

$ http POST http://0.0.0.0:8080/v1/log/ logs:='["error1", "error2"]'

Just returns 200 OK. As Apple puts it:

This endpoint is intended to help you debug your web service implementation. Log messages contain a description of the error in a human-readable format.

Licence

jersey-passbook is available under the MIT licence. Please see LICENCE for further information.