paljs / prisma-tools

Prisma tools to help you generate CRUD system for GraphQL servers
https://paljs.com
MIT License
684 stars 54 forks source link

Mapping of types between graphql and prisma #131

Closed kuksik closed 3 years ago

kuksik commented 3 years ago

I have something like:

schema.prisma `

model someEntity {
    id                        string
    name                  string
    additionaField    string
  }

`

types.graphql `

type someEntityCustom {
    id                        string
    name                  string
  }

`

I have investigated codebase of select method and see that it try to find model with name someEntityCustom. But that model does not exists in the DB. How i can map graphql type and prisma model?

Looks like valueOf can do something similar but i can not understand how to use it in right way

AhmedElywa commented 3 years ago

@kuksik we use model name to make filter before return fields and exclude any field, not in the schema model.

you can easily add custom type as you need and will return the fields you select but you must be sure that these fields exist in schema model or prisma client will throw error

kuksik commented 3 years ago

What about custom fields in the custom type?

AhmedElywa commented 3 years ago

in this case, you can use valueWithFilter method in new version 1.5.5

kuksik commented 3 years ago

@AhmedElywa i will try explain my problem with more details:

schema.prisma `

model Config {
   id                        string
   configName       string
}

model Configs {
    id                        string
    config1               Config
    config2               Config
    config3               Config
  }

`

types.graphql `

type ConfigType {
     id                        string
     additionField      string 
     configName       string
 }
 type Configs {
     id                        string
     config1               ConfigType
     config2               ConfigType
     config3               ConfigType
}

`

I implemented resolver which do what i need: map my custom types from graphql with prisma models.

resolver.ts `

Query: {
    configs: (parent, args, ctx, info) => {
        // info looks like:
        // info = `id config1 { id additionField } config2 { id additionField } config3 { id additionField configName }` 

        const select = ctx.PrismaSelect(info);
        const config1 = select.valueOf('configs.config1', 'Config');
        const config2 = select.valueOf('configs.config3', 'Config');
        const config3 = select.valueOf('configs.config3', 'Config');

         select.select.configs.select.config1 = config1;
         select.select.configs.select.config2 = config2;
         select.select.configs.select.config3 = config3;

         return await ctx.prisma.configs.findMany({ ...params, ...select });
    }
 }

` This code works but looks very massive and it is difficult to maintenance for more complex schema.

Possible solution. Will be cool if we have map object which will describe relations between graphql types and prisma models. If model with type name does not exist in the db then select will get model name from map object. `

....
PrismaSelect: (info: any): PrismaSelect => {
      const typeModelMap = {
          config1: 'Config'
          config2: 'Config'
          config3: 'Config',
        }
      };
      return new PrismaSelect(info, null, typeModelMap);
 ... 

`

AhmedElywa commented 3 years ago

Will see how we can make this and back to you

AhmedElywa commented 3 years ago

Why you don't add this field in the original type name

kuksik commented 3 years ago

I do not need this field i the DB because I need reuse the same item for different hierarchal items, and i add this field in the code

AhmedElywa commented 3 years ago

What I mean why you name type ConfigType instead of Config

kuksik commented 3 years ago

ah, ok. I use Config type too. ConfigType is client oriented type.

AhmedElywa commented 3 years ago

Ok wait for a workaround this

AhmedElywa commented 3 years ago

The idea now is adding a comment on the schema.prisma file like this

It will be array so you can create custom types as you want

I will look to original name and all names in map

/// PrismaSelect.map([ConfigType, ConfigCustomType])
model Config {
   id               string
   configName       string
}
AhmedElywa commented 3 years ago

@kuksik please upgrade to version 1.5.6 try now to add

/// @PrismaSelect.map([ConfigType])
model Config {
   id               string
   configName       string
}
AhmedElywa commented 3 years ago

@kuksik any test here to confirm that your issue is done?