Skip to content

Conversation

@rtyley
Copy link
Member

@rtyley rtyley commented Oct 2, 2025

When completed, this will unblock us from using the most recent versions of Thrift & Scrooge, which started rejecting Thrift definitions that uses the reserved word end some time ago:

This has had a heavy knock-on effect at the Guardian as we've had Thrift fields named end in this repo since its initial commit in 2016:

10: optional CapiDateTime start
11: optional CapiDateTime end

To avoiding renaming the fields we've had to resort to using older versions of these libraries that don't have these restrictions:

In order to ensure we can use the most recent versions of those libraries, we need to pay the price: we need to rename the fields.

Testing

Happily, there is a great test within this repo that tests for JSON-conformance for one of the affected Thrift types:

it should "round-trip an ItemResponse with a membership element" in {
checkRoundTrip[ItemResponse]("item-content-with-membership-element.json")
}

This test fails if we just naively rename the end field - this will be a starting point for checking that we remain compatible with JSON parsers.

See also

@rtyley rtyley changed the title Rename end field that uses reserved Thrift word Rename fields named with reserved Thrift words: ie end Oct 2, 2025
@rtyley rtyley changed the title Rename fields named with reserved Thrift words: ie end Rename Thrift fields named with reserved Thrift words (ie end) while preserving JSON compatibility Oct 2, 2025
@rtyley rtyley changed the title Rename Thrift fields named with reserved Thrift words (ie end) while preserving JSON compatibility Rename Thrift fields named with reserved words (ie end) while preserving JSON compatibility Oct 2, 2025
To keep using the old names in the json produced and consumed by these
encoders and decoders, it should be possible to use circe-generic-extras
to define configured encoders and decoders that do the field renaming.

However, this currently fails because deriveConfiguredEncoder and
deriveConfiguredDecoder can’t tell that it’s possible to use fezziwig to
get the necessary shapeless representations they can normally get
already for case classes and traits.

It might be possible to update fezziwig to support using it with
circe-generic-extras (by outputting whatever deriveConfiguredEncoder
needs that deriveEncoder doesn’t), but it’s probably easier to avoid
using circe-generic-extras altogether: I’ll investigate that
next. (Keeping this commit around for history.)
Since the changes required are pretty straightforward, it’s easier to
use .prepare and .mapJson rather than get circe-generic-extras working
with fezziwig. However, this does mean we need to check this code quite
carefully: working directly with Json means we lose a lot of static
typing guarantees, which we will want to get back with tests.

(For example, as it is this doesn’t handle the case where only one of
the fields is present correctly!)
@emdash-ie
Copy link
Contributor

I expect the changes I have pushed should get the tests passing on this branch. However, this does not mean they work fully yet! We need to add more tests to confirm, for example one which attempts to encode/decode json with only one of the startDate and endDate fields (which I expect to fail at the moment).

It might also be nice to have some tests verifying that code using the old thrift definitions pre-renaming and code using the new thrift definitions post-renaming will be able to communicate back and forth using either json (from these circe encoders and decoders) or thrift binary encoding.

These tests exercise the case I mentioned in the last commit, by
omitting the start date from the latter test’s json. Fixing the bug
should fix this test, I’ll do that next.
This commit fixes the renaming of fields by still working if one of them
is missing. (Replacing the single for-expression with two composed
.maps.)
@emdash-ie
Copy link
Contributor

I wanted to confirm that we haven’t used any other reserved words, so I did some digging to find the list. However, it turns out thrift actually only defines reserved words per-language. So it is scrooge’s mistake to be forcing us not to use end, when end does not appear in the list of java reserved words.

For reference, the latter are currently:

abstract
assert
boolean
break
byte
case
catch
char
class
const
continue
default
do
double
else
enum
extends
false
final
finally
float
for
goto
if
implements
import
instanceof
int
interface
long
native
new
null
package
private
protected
public
return
short
static
strictfp
super
switch
synchronized
this
throw
throws
transient
true
try
void
volatile
while

I will search for any uses of those in our thrift definitions.

@emdash-ie
Copy link
Contributor

I will search for any uses of those in our thrift definitions.

I think this search means we’re safe.

@rtyley rtyley changed the title Rename Thrift fields named with reserved words (ie end) while preserving JSON compatibility Rename Thrift fields to avoid reserved words (ie end) while preserving JSON compatibility Oct 7, 2025
@emdash-ie
Copy link
Contributor

We should check if this field name is also used in thrift in flexible-model, and whether we need to make a similar change there.

@emdash-ie
Copy link
Contributor

We should check if this field name is also used in thrift in flexible-model, and whether we need to make a similar change there.

It looks like the same field name exists in flexible-model in ElementFields and MembershipElementFields. What I’m not sure of is how exactly these thrift definitions are used: are they used for any serialisation/deserialisation that uses the field names?

@emdash-ie
Copy link
Contributor

I have raised https://github.com/guardian/flexible-model/pull/85 to rename the fields in flexible-model. There aren’t any jsony uses of the field names in that model that I can see, but I think we’ll probably need to check the apps that use this library, especially any with dependencies on fezziwig. Doing some searching, I think the apps which depend on flexible-model are mainly porter, composer itself, and workflow.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants