govuk_content_item_loader 1.0.0 → 1.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 2a533cf2cd72d38cfd19f7ef5555bb14c93156638ff6220d1dd494d92550a390
4
- data.tar.gz: a1e9a897b7b82e747d81434c1d5965d550507edaa3a2a5ae4abde20df63e62ac
3
+ metadata.gz: 947921788377a6a5dd65917c2f546d8baaabbab0183a9673df551a064b422457
4
+ data.tar.gz: 9aecaf319b535faa6172cf652cd195e89dadc0dd92858db2c25b9737309b9e48
5
5
  SHA512:
6
- metadata.gz: 85e6a82e33eb3fab62a93bfda0eeff17314f6ac79b4a6e9f2f09b138cbfa5c9c3812557b0638a5d294d9f28c790ee5f6b2e24293b28bd7042699e17c13b037b3
7
- data.tar.gz: 7fd62a7aecc2bd6a214a92c6576a0469b3766d548ba699326f9798f7330d2f7b8fa5a219fca55fdac83e064aff2bd5a0e3ffe664ac1518ac6c8b36fe22af35f1
6
+ metadata.gz: 6f5f426102604ffce580a33b0fead1eb99d623f4500cd308669bf95b4ab49d9239e7d4dab37917ce32a513ec28cc3a8682c09833aca0136bff5cee5b7a443c0a
7
+ data.tar.gz: ee6e8a19ff172558e8aaa0a86c80c189f41213f09cc1715e00e18b2e0be62d32d7e40a815ec745880c197f97135c7d622b57725050a5ad2120989fe334bb9ebf
@@ -6,7 +6,5 @@ on:
6
6
  jobs:
7
7
  autorelease:
8
8
  uses: alphagov/govuk-infrastructure/.github/workflows/autorelease-rubygem.yml@main
9
- with:
10
- gem_name: content_block_tools
11
9
  secrets:
12
10
  GH_TOKEN: ${{ secrets.GOVUK_CI_GITHUB_API_TOKEN }}
@@ -38,7 +38,7 @@ jobs:
38
38
  - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
39
39
  with:
40
40
  ref: ${{ inputs.ref || github.ref }}
41
- - uses: ruby/setup-ruby@09a7688d3b55cf0e976497ff046b70949eeaccfd # v1.288.0
41
+ - uses: ruby/setup-ruby@6ca151fd1bfcfd6fe0c4eb6837eb0584d0134a0c # v1.290.0
42
42
  with:
43
43
  ruby-version: ${{ matrix.ruby }}
44
44
  bundler-cache: true
data/CHANGELOG.md CHANGED
@@ -1,5 +1,9 @@
1
1
  # Changelog
2
2
 
3
+ ## 1.1.0
4
+
5
+ - Add Content Store fallback for failed Graphql requests
6
+
3
7
  ## 1.0.0
4
8
 
5
9
  - Add GraphQL traffic rates initializer.
@@ -0,0 +1,73 @@
1
+ # ADR 1: Create a dedicated gem for conditional GraphQL content loading
2
+ Status: Accepted
3
+ Date: 2026-02-17
4
+
5
+ ## Context
6
+ As part of the migration to GraphQL-backed content retrieval [RFC-172](https://github.com/alphagov/govuk-rfcs/blob/main/rfc-172-graphql-for-govuk.md), we are introducing a temporary (medium-term) ConditionalContentItemLoader that determines whether a request should load content from:
7
+ * The Content Store (REST), or
8
+ * The Publishing API via GraphQL
9
+
10
+ This decision is made at request time and depends on:
11
+ * Request parameters
12
+ * Environment state (e.g. draft host)
13
+ * Allow-list configuration
14
+ * Probabilistic traffic splitting
15
+
16
+ It includes Prometheus metrics labelling for monitoring and alerting.
17
+
18
+ The loader is required across seven frontend applications.
19
+
20
+ ## Problem
21
+ We need a centralised implementation to:
22
+ * Avoid duplication and divergence across multiple apps
23
+ * Maintain clear architectural boundaries
24
+ * Keep configuration and routing logic co-located
25
+
26
+ ## Decision
27
+ We will create a Ruby gem to encapsulate the conditional content loader and its configuration, with minimal dependencies.
28
+
29
+ ## Rationale
30
+ 1. Shared across multiple applications
31
+ One gem ensures consistent behaviour and easier rollout coordination.
32
+
33
+ 1. Maintenance burden is acceptable
34
+ The gem is small, with few dependencies.
35
+
36
+ 1. Not a good fit for `gds-api-adapters`
37
+ `gds-api-adapters` is designed around a clear architectural pattern:
38
+ * Each adapter corresponds to a single external API
39
+ * Adapter methods map directly to HTTP endpoints
40
+ * Namespaces reflect a 1:1 relationship with APIs
41
+
42
+ The conditional loader does not fit this model as it's a higher-level orchestration layer, not a client abstraction. Adding it to gds-api-adapters would:
43
+ * Blur architectural boundaries
44
+ * Violate separation of concerns
45
+ * Break the established software design pattern of the gem
46
+
47
+ 1. Not a good fit for `govuk_app_config`
48
+ That library is intended for generic application configuration, not behaviour orchestration used by a subset of apps.
49
+
50
+ 1. Explicitly not using `govuk_ab_testing`
51
+ `govuk_ab_testing` was considered. This is not a generic A/B test or experiment framework use case. Embedding this logic in govuk_ab_testing would conflate experimentation infrastructure with migration routing logic.
52
+
53
+ 1. Co-location with configuration
54
+ The loader depends on configuration established via GovukGraphqlTrafficRates.configure which would fit in govuk_app_config. However, keeping it in the same gem reduces complexity and risk of misconfiguration.
55
+
56
+ ## Alternatives considered
57
+ - Duplicate in each app – rejected due to divergence risk.
58
+ - Add to `gds-api-adapters` – rejected; violates separation of concerns.
59
+ - Add to `govuk_app_config` – rejected; not just application configuration.
60
+ - Add to `govuk_ab_testing` – rejected; not experimentation logic.
61
+
62
+ ## Consequences
63
+
64
+ ### Positive
65
+ * Consistent behaviour across multiple applications
66
+ * Clean architectural separation
67
+ * Centralised rollout
68
+ * Clear ownership of GraphQL migration logic
69
+ * Versioned upgrades
70
+
71
+ ### Negative
72
+ * One additional gem to maintain
73
+ * Increase in dependency management overhead
@@ -9,7 +9,9 @@ class GovukConditionalContentItemLoader
9
9
  end
10
10
 
11
11
  def load
12
- can_load_from_graphql? ? content_item_from_graphql : content_item_from_content_store
12
+ return content_item_from_content_store unless can_load_from_graphql?
13
+
14
+ content_item_from_graphql || content_item_from_content_store
13
15
  end
14
16
 
15
17
  def can_load_from_graphql?
@@ -32,10 +34,10 @@ private
32
34
  publishing_api_client.graphql_live_content_item(base_path)
33
35
  rescue GdsApi::HTTPErrorResponse => e
34
36
  set_prometheus_labels(graphql_status_code: e.code)
35
- raise e
36
- rescue GdsApi::TimedOutException => e
37
+ false
38
+ rescue GdsApi::TimedOutException
37
39
  set_prometheus_labels(graphql_api_timeout: true)
38
- raise e
40
+ false
39
41
  end
40
42
 
41
43
  def content_item_from_content_store
@@ -1,3 +1,3 @@
1
1
  module GovukContentItemLoader
2
- VERSION = "1.0.0".freeze
2
+ VERSION = "1.1.0".freeze
3
3
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: govuk_content_item_loader
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.0
4
+ version: 1.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - GOV.UK Dev
@@ -157,6 +157,7 @@ files:
157
157
  - LICENCE
158
158
  - README.md
159
159
  - Rakefile
160
+ - docs/adr/01-new-gem-for-conditional-content-loading.md
160
161
  - govuk_content_item_loader.gemspec
161
162
  - lib/govuk_content_item_loader.rb
162
163
  - lib/govuk_content_item_loader/govuk_conditional_content_item_loader.rb
@@ -180,7 +181,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
180
181
  - !ruby/object:Gem::Version
181
182
  version: '0'
182
183
  requirements: []
183
- rubygems_version: 4.0.6
184
+ rubygems_version: 4.0.7
184
185
  specification_version: 4
185
186
  summary: Provides a standardised content item loader for GOV.UK frontend apps with
186
187
  configurable GraphQL traffic routing and automatic fallback to the Content Store