Skip to content

feat(backend): cache Discord API requests - #574

Draft
jaskfla wants to merge 18 commits into
mainfrom
cache-discord-reqs
Draft

feat(backend): cache Discord API requests#574
jaskfla wants to merge 18 commits into
mainfrom
cache-discord-reqs

Conversation

@jaskfla

@jaskfla jaskfla commented May 19, 2026

Copy link
Copy Markdown
Collaborator

Note

Had started work on this, but then momentum trailed off.

This PR is missing unit tests and has not been comprehensively manually tested. Cursory smoke testing in local dev environment hasn’t raised any flags, but I’m not comfortable deploying without more thorough testing.

You’ll see I’ve implemented cache.invalidate(), but don’t actually call it anywhere; but only because I haven’t reviewed the endpoints to see which ones warrant imperative invalidation.

🥞 Stack

  1. feat(backend): cache Discord API requests #574 👈
  2. feat(backend): caching middleware #575

@jaskfla

jaskfla commented May 19, 2026

Copy link
Copy Markdown
Collaborator Author

@stijnvdkolk I understand from @Rocked03 you’re working on something related to guild memberships. We figure you might have some thoughts?

Comment thread packages/backend/src/app/Cache.ts Fixed
@jaskfla
jaskfla force-pushed the cache-discord-reqs branch from 1031389 to 9abb2cc Compare May 19, 2026 21:26
@stijnvdkolk

Copy link
Copy Markdown
Contributor

@stijnvdkolk I understand from @Rocked03 you’re working on something related to guild memberships. We figure you might have some thoughts?

Yeah I did some stuff with guild membership caching in #562 so we don't always fetch the new guild memberships. Will look through this PR sometime tomorrow 🙌

@Rocked03

Copy link
Copy Markdown
Member

@stijnvdkolk I understand from @Rocked03 you’re working on something related to guild memberships. We figure you might have some thoughts?

Yeah I did some stuff with guild membership caching in #562 so we don't always fetch the new guild memberships. Will look through this PR sometime tomorrow 🙌

bumping :)

@stijnvdkolk

Copy link
Copy Markdown
Contributor

@stijnvdkolk I understand from @Rocked03 you’re working on something related to guild memberships. We figure you might have some thoughts?

Yeah I did some stuff with guild membership caching in #562 so we don't always fetch the new guild memberships. Will look through this PR sometime tomorrow 🙌

bumping :)

Hope to be able to get to it today, got some other things that came in between yesterday!

Comment thread packages/backend/src/discord-api/DiscordApiClient.ts Outdated
Comment thread packages/backend/src/discord-api/DiscordApiClient.ts Outdated
return await fetchWithRetries(url, init, retryOptions);
}

const cacheKey = `${url.pathname}${url.search}`;

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's global, not per user.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Saw you made it based on token, is that smart? There is a part of the token that is the user id, cant we just only take that part and leave the rest out? Might be a bit more secure

@jaskfla jaskfla May 28, 2026

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

is that smart

Not really. If you snoop around the commit history you’ll see that I described it as rudimentary user scoping or something like that 😅

Realistically I’m not that worried because it’s in memory in the backend. My bigger issue with this is just that it’s rather inelegant. I didn’t realise the user ID was baked into the JWT; I’ll look into that. It was my first instinct to use user ID, but I thought I had to go through 3–4 layers of dependency injection

My other gripe is that if you provide the same search params in a different order, it’s a cache miss. Originally hoped keys could just be deterministically derived from the request, but might end up putting burden on the dev to come up with sensible keys like TanStack QueryKeys. Not sure yet

All of which is to say: still working on it! 👷

Comment thread packages/backend/src/discord-api/DiscordApiClient.ts Outdated
}

class DiscordApiClient {
declare baseUrl: string;

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Are you sure that we need declare here?

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Apparently so 🤷

Property 'baseUrl' does not exist on type 'DiscordApiClient'.ts(2339)

Comment on lines +5 to +7
function logWithTag(...args: Parameters<typeof console.debug>) {
console.debug(styleText(["dim"], "[DiscordApiClient]"), ...args);
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I feel like we are using a variants of this in multiple places, can we pull this out and make a full logger setup? Might be worth it to do this in a separate PR.

@jaskfla jaskfla May 27, 2026

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Def on board with setting up proper logging. Just realised we don’t even have Morgan (or equivalent) at the moment? 🥴

When you say pull this out, do you mean just remove all logging-related additions from this PR?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No, just keep it like this for now, and pick it up separately, there is a separate issue for it, but we could look into a short time fix to streamline it a bit what we already have if you want by just copying these functions in a shared file that we can use in the other places too, before we switch to a better logging solution

Comment thread packages/backend/src/app/Cache.ts Outdated
Comment thread packages/backend/src/services/discordGuildService.ts Outdated
Comment thread packages/backend/src/app/Cache.ts Outdated
Comment thread packages/backend/src/app/Cache.ts
@Rocked03

Copy link
Copy Markdown
Member

Any chance we can give this a nudge please?

@jaskfla

jaskfla commented May 27, 2026

Copy link
Copy Markdown
Collaborator Author

Any chance we can give this a nudge please?

Oh, are you wanting to release this mid-event? It’s a bit of a high-risk change

Comment on lines +20 to +26
function sanitizeRequestInit(requestInit: RequestInit): RequestInit {
const headersInit = requestInit.headers;
if (headersInit === undefined) return requestInit;
const headers = new Headers(headersInit);
headers.delete("Authorization");
return { ...requestInit, headers };
}

@jaskfla jaskfla May 27, 2026

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would’ve been nice to keep the whatever shape HeadersInit was supplied in, but:

  • Headers interface matches case-insensitively, whereas [string, string][] and { [key: string]: string } requires more manual work; and
  • normalising for a production log feels fine to me. In local dev we can just console.log the entire thing with no redactions

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