API to publish content on GOV.UK
Ruby Other
Switch branches/tags
Clone or download
cbaines Merge pull request #1289 from alphagov/drop-need-ids-column
Drop the need_ids column from the editions table
Latest commit b132f42 Jul 19, 2018
Failed to load latest commit information.
app Fix a couple of typos in content_dependencies.rb Jul 11, 2018
bench Fix deleting links in the benchmark scripts Apr 27, 2018
bin Updated configs for Rails 5.1. May 15, 2017
config Decrease Sidekiq concurrency from 10 to 6 Jul 11, 2018
db Drop the need_ids column from the editions table Jul 19, 2018
doc GET /v2/editions can now filter on document_types Jul 3, 2018
lib Merge pull request #1253 from alphagov/whitehall-eu-exit-report Jun 26, 2018
log Bare Rails application Jul 29, 2015
spec Merge pull request #1275 from alphagov/include_document_types Jul 3, 2018
.dockerignore Ignore only the files inside logs, not entire directory Jan 9, 2017
.gitignore Enables --only-failures and --next-failure in rspec Dec 14, 2016
.rspec Use rspec-rails for testing Jul 29, 2015
.rubocop.yml Disable RuboCop forcing SymbolArray in lib/expansion_rules.rb Mar 13, 2018
.ruby-version Update .ruby-version to 2.4.4 Apr 10, 2018
CONTRIBUTING.md Add a contributing document that includes info on data migrations May 23, 2017
Dockerfile Update Dockerfile to 2.4.4 Apr 10, 2018
Gemfile Merge pull request #1276 from alphagov/dependabot/bundler/with_adviso… Jul 18, 2018
Gemfile.lock Merge pull request #1276 from alphagov/dependabot/bundler/with_adviso… Jul 18, 2018
Jenkinsfile Pin tests to run on Postgres 9.3 Jun 19, 2018
LICENSE Correct the owner of the copyright Mar 4, 2015
Procfile Use unicorn in the procfile Jan 31, 2018
README.md Highlight syntax in README.md Jun 27, 2017
Rakefile Move pact rake task definitions to their own file Sep 18, 2015
config.ru Bare Rails application Jul 29, 2015
docker_tests.sh Run tests locally using Docker Dec 15, 2016
startup.sh Revert using foreman in dev environment Feb 23, 2018


Publishing API

The Publishing API aims to provide workflow as a service so that common publishing features can be written once and used by all publishing applications across Government. Content can be stored and retrieved using the API and workflow actions can be performed, such as creating a new draft or publishing an existing piece of content.


  • Document: A document is a piece of content in a particular locale. It is associated with editions that represent the versions of the document.
  • Edition: The content of a document is represented by an edition, it represents a distinct version of a Document.
  • Content Item: A representation of content that can be sent to a content store.
  • Links: Used to capture relationships between pieces of content (e.g. parent/child). Can be of type link set link or edition link.
  • Unpublishing: An object indicating a previously published edition which has been removed from the live site.
  • User: A user of the system, which is used to track who initiated requests and to restrict access to draft content.
  • Path Reservation: An object that attributes a path on GOV.UK to a piece of content. It is used when paths need to be reserved before that content enters the system.
  • Event Log: A log of all requests to the Publishing API that have the potential to mutate its internal state.
  • Action: A record of activity on a particular edition, used to assist custom workflows of publishing applications.
  • Link Expansion: A process that converts the stored and automatic links for an edition into a JSON representation.
  • Dependency Resolution: A process that determines other editions that require updating downstream as a result of a change to an edition.

Technical documentation

The Publishing API is a Ruby on Rails application that exposes an internal API to publishing applications. It stores its data in a Postgresql database and sends content downstream to the draft and live Content Stores as well as on a Rabbit message queue. Some of the processing of requests is handled asynchronously through Sidekiq which stores jobs in Redis.

The endpoints of the Publishing API are documented in doc/api.md.

Decisions about the design of the Publishing API are recorded as architecture decision records in the doc/arch directory.

Deleting Documents, Editions and Links

To delete content from the Publishing API you will need to create a data migration.

If you need to delete all traces of a document from the system:

require_relative "helpers/delete_content"

class RemoveYourDocument < ActiveRecord::Migration
  # Remove /some/base-path
  def up

If you need to delete a single edition:

require_relative "helpers/delete_content"

class RemoveYourEdition < ActiveRecord::Migration
  def up
    editions = Edition.where(id: 123)



If you need to delete just the links for a document:

require_relative "helpers/delete_content"

class RemoveLinks < ActiveRecord::Migration
  # Remove /some/base-path
  def up


  • postgres - the app uses a postgres database
  • redis - the Sidekiq worker stores its jobs in Redis
  • alphagov/content-store - content is sent to multiple content-stores (draft and live)

These dependencies are set up on the dev vm and if you use bowl to run the app, it will start both the draft and live content store for you. For more information about RabbitMQ, see doc/rabbitmq.md.

Running the application


It downloads and installs dependencies and starts the app on port 3093. When using GOV.UK virtual machine the app is available at publishing-api.dev.gov.uk.

Running the test suite

You can run the tests locally with: bundle exec rake.

The publishing API includes contract tests which verify that the service behaves in the way expected by its clients. We use a library called pact which follows the consumer driven contract testing pattern. You can run the pact verification tests on their own using:

$ bundle exec rake pact:verify

See doc/pact_testing.md for more details about the pacts and the pact broker.

Example API requests

curl https://publishing-api.dev.gov.uk/content/<content_id> \
  -X PUT \
  -H 'Content-type: application/json' \
  -d '<content_json>'

See doc/api.md and the pact broker for more information.


Events older then a month are archived to S3, you can import these events back into your local DB by running the rake tasks in lib/tasks/events.rake, after you set up the relevant ENV variables. For example if you want to find all the events that are relevant for a particular content id you can run:

rake 'events:import_content_id_events[a796ca43-021b-4960-9c99-f41bb8ef2266]'

See the rake task for more details.

Admin tasks

See admin tasks for more information


See the contributing documentation for more information.


MIT License