No full post here yet. Just some musings on how I've been approaching entity normalisation at scale.

  • GraphQL makes an excellent transport layer and query definition layer

  • I'm finding that it falls short for entity normalisation and 'simple' client interfaces.

  • GraphQL:

    1query ABC {
    2 rider(id: $id) {
    3 id
    4 orders {
    5 id
    6 title
    7 status
    8 }
    9 }
    10}
    11
    12const result = await graphQL.query(ABC);
    13result; // some json document
    14
    15// Just want the orders?
    16... I assume some graphql specific mechanic to get them

    Hypothetical namespace/entity data layer

    1const rider = await Rider.byId('abc', { orders: true });
    2const recentOrder = await Orders.byRelation('rider', 'abc');
    3const inflatedRestObject = await Rider. Rider.byId('abc', { orders: true }, { inflate: true }); // { id, orders: [{ id, status: 'x' ... }

    Definitely just re-inventing a database here

    I actually quite dislike the field-level control GraphQL gives you. Maybe I've gone REST native. It seems to be the only optional fields in an API should be relationships, edges, connections to other entities. If the DB is joining to create fields on a single response object then in my mind it is probably just as efficient to let it do it rather than maintaining multiple shapes for the same entity.

    In a relationship scenario, then optional params make sense.

    ☕️ Made with Intenso