Skip to content
This repository has been archived by the owner on Dec 4, 2023. It is now read-only.

Thinking out loud about v2 of this library #62

Closed
Asjas opened this issue Mar 14, 2022 · 1 comment · Fixed by #69
Closed

Thinking out loud about v2 of this library #62

Asjas opened this issue Mar 14, 2022 · 1 comment · Fixed by #69
Assignees
Labels
enhancement New feature or request

Comments

@Asjas
Copy link
Owner

Asjas commented Mar 14, 2022

At the moment this Prisma middleware isn't very flexible and I feel that the caching API isn't that nice to use.

prismaClient.$use(
  createPrismaRedisCache({
    models: ["User", "Post"],
    cacheTime: 300,
    redis,
    excludeCacheMethods: ["findMany"],
  }),
);

I want to update the API to possibly look like this:

  • models: Array of objects. The key is the model to cache and the value is the time to cache it.
  • excludeModels: Array of strings. These models will NOT be cached.
  • redis: Optional. Falls back to using an in-memory LRU cache
  • cacheTime: Still an integer
  • excludeCacheMethods: Still an array of methods to ignore when caching

Example 1:

prismaClient.$use(
  createPrismaRedisCache({
    cacheTime: 300,
  }),
);

You can invoke the middleware while leaving the models out which will cause all models to be cached based on cacheTime.

And if you leave the redis instance out this should fall back to using an in-memory LRU cache. This should make it easier for someone to test this in development without needing to configure or install Redis.

Thoughts: In such a case it should print out a warning stating that an in-memory cache is being used and that you should pass a Redis instance to persist the cache.

Example 2:

prismaClient.$use(
  createPrismaRedisCache({
    models: [{ "User", 300 }, { "Post": 900 }],
    cacheTime: 300,
    redis,
    excludeCacheMethods: ["findMany"],
  }),
);

You can specify the caching time per model.

The global cacheTime middleware option is then used for any other Model that isn't explicitly specified in models.

You can then specify a value of 0 to cacheTime or leave the cacheTime option out to stop it from caching any explicit models you didn't specify.

Some thoughts about the models API

I don't know if I want the models to have an API that looks like this.

 models: [{ "User", 300 }, { "Post": 900 }],

Or like this:

 models: [{ model: "User", cacheTime: 300 }, { model: "Post", cacheTime: 900 }],

I like the 2nd one, but it also feels a slightly verbose... 🤔


Some other thoughts.

  1. Should I just ignore cacheTime if there is a models value (which will include a caching value per model)? Or should I use it for any model that isn't specified?

  2. Allowing someone to specify their own caching key per model...? yikes

  3. Allowing an option called excludeModels which could be an Array of strings which will NOT be cached?

@Asjas Asjas added the enhancement New feature or request label Mar 14, 2022
@Asjas Asjas self-assigned this Mar 14, 2022
@Asjas Asjas pinned this issue Mar 14, 2022
@Asjas
Copy link
Owner Author

Asjas commented Mar 18, 2022

The createPrismaRedisCache API I decided on is represented as this TypeScript type.

export type PrismaMutationAction =
  | "create"
  | "createMany"
  | "update"
  | "updateMany"
  | "upsert"
  | "delete"
  | "deleteMany"
  | "executeRawUnsafe";

export type PrismaQueryAction =
  | "findFirst"
  | "findUnique"
  | "findMany"
  | "aggregate"
  | "count"
  | "groupBy"
  | "queryRaw";

export type PrismaAction = PrismaMutationAction | PrismaQueryAction;

export type RedisMemoryOptions = {
  client: Redis.Redis;
  invalidation?: boolean | { referencesTTL?: number };
  log?: any;
};

export type MemoryStorageOptions = {
  size?: number;
  invalidation?: boolean;
  log?: any;
};

export type CreatePrismaRedisCache = {
  models?: [
    {
      model: string;
      primaryKey?: string;
      cacheTime?: number;
      excludeCacheMethods?: [PrismaQueryAction];
    },
  ];
  storage?:
    | {
        type: "redis";
        options?: RedisMemoryOptions;
      }
    | {
        type: "memory";
        options?: MemoryStorageOptions;
      };
  defaultCacheTime?: number;
  defaultExcludeCacheModels?: [string];
  defaultExcludeCacheMethods?: [PrismaQueryAction];
  onError?: () => void;
  onHit?: () => void;
  onMiss?: () => void;
  onDedupe?: () => void;
};

@Asjas Asjas closed this as completed Mar 28, 2022
@Asjas Asjas unpinned this issue Mar 29, 2022
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
enhancement New feature or request
Projects
None yet
Development

Successfully merging a pull request may close this issue.

1 participant