tRPCttRPC
Powered by
rustclanR
tRPCβ€’3y agoβ€’
19 replies
rustclan

TRPC ratelimiting endpoints

I am currently having some problems with a race condition in my TRPC nextJS api.

Essentially what is happening is I have a
enforceGuildPermissions
enforceGuildPermissions
method, which basically checks if the user who is making the request has permission to get the data for that guild.

The data is stored in my Redis cache for 3 seconds. This works okay sometimes, but other times because there is 3-4 different trpc requests running for a single page which are guild, role and channel. It causes the last request (channel) to get rate limited by the discord API because they are all running concurrently, this means it doesn't give my caching code chance to update it before the next one runs.

middleware route procedure:
const enforceGuildPermissions = enforceUserLoggedIn.unstable_pipe(
  async ({ ctx, next, rawInput }) => {
    const guildId: unknown = (rawInput as { guildId?: unknown })?.guildId;
    if (!guildId) throw new TRPCError({ code: 'BAD_REQUEST' });

    const webUser = await cache.webUsers.get(ctx.session.user.id);
    let guilds = webUser?.guilds;
    if (!guilds) {
      guilds = await getUserGuilds(ctx.session)

    }

    if (!guilds) throw new TRPCError({ code: 'UNAUTHORIZED' });
    
    // if the user is not in the guild return unauth
    const foundGuild = guilds.find((guild) => guild.id === guildId);
    if (!foundGuild) throw new TRPCError({ code: 'UNAUTHORIZED' });

    return next({
      ctx: {
        session: { ...ctx.session, user: ctx.session.user },
      },
    });
  }
);

export const guildProcedure = t.procedure.use(enforceGuildPermissions);
const enforceGuildPermissions = enforceUserLoggedIn.unstable_pipe(
  async ({ ctx, next, rawInput }) => {
    const guildId: unknown = (rawInput as { guildId?: unknown })?.guildId;
    if (!guildId) throw new TRPCError({ code: 'BAD_REQUEST' });

    const webUser = await cache.webUsers.get(ctx.session.user.id);
    let guilds = webUser?.guilds;
    if (!guilds) {
      guilds = await getUserGuilds(ctx.session)

    }

    if (!guilds) throw new TRPCError({ code: 'UNAUTHORIZED' });
    
    // if the user is not in the guild return unauth
    const foundGuild = guilds.find((guild) => guild.id === guildId);
    if (!foundGuild) throw new TRPCError({ code: 'UNAUTHORIZED' });

    return next({
      ctx: {
        session: { ...ctx.session, user: ctx.session.user },
      },
    });
  }
);

export const guildProcedure = t.procedure.use(enforceGuildPermissions);
tRPCJoin
Move Fast & Break Nothing. End-to-end typesafe APIs made easy.
5,015Members
Resources
Recent Announcements

Similar Threads

Was this page helpful?

Similar Threads

Call multiple TRPC endpoints from onSuccess()?
peternovakPpeternovak / ❓-help
3y ago
cant access trpc endpoints via the browser
SonSSon / ❓-help
4y ago
Security: DDOS attack prevention for open endpoints tRPC
WhoamIWWhoamI / ❓-help
3y ago