feathersjs-ecosystem/feathers-knex

Dynamically changing the knex schema based on request

Opened this issue · 0 comments

I need a way to dynamically change which schema is used for for a service in a multi tenancy app. I see there was an option added to the options where you can specify the schema, but that doesn't help for selecting it based on request. I could force change this.schema in the service on every request, but that feels bad as its then storing it based on the last user request.

What I'm trying to do is load data for different companies based on which the user has selected. Each companies data is stored in a separate schema to keep data isolated.

There was a merge request years ago for adding schema to the the params object #255, but that is stagnant. Looks like it really only adds 1 line of code, but has funky behavior for getFullname as the schema is stored. I don't think thats an issue though as I cant see a use case for getFullname in this scenario or would have any effect on existing code. If this was merged it would allow for this.

// Client
app.service('vendors').find({
    query: {
        schema: 'company-name',
    },
});

// Server Hook
(context: HookContext) => {
  context.params.schema = context.params?.query?.schema;
} 

An alternative would be to specify a new knex object to use on request. I also see another option issue for changing params.knex from 2017 #117. I tried setting params.knex but it doesn't seem to have any effect on the query. Looking at the code its also only used in the _find function, so would this even apply to the other service methods if it did work? Heres a hook I'm adding to my service to set the knex instance with the schema:

(context: HookContext) => {
  context.params.knex = context.app.get('knex').withSchema(context.params?.query?.schema);
} 

Additional Question

I've read that only the query object is passed to the server. Because of that I added the schema to the query, but this could cause issues if you had a column named schema. I'd like to pass that info any other way. Should #255 be merged, is it possible to set the schema param from the client side?

app.service('vendors').find({
    query: {
        ...
    },
   schema: 'company-name',
});

Module versions (especially the part that's not working):
feathers-knex: 7.1.1

NodeJS version:
v14.16.0

Operating System:
Windows 10

Browser Version:
N/A

React Native Version:
N/A

Module Loader:
N/A