Nexus-plugin-prisma: Prisma2: Support for loading all fields and crud operations like in prisma 1

Created on 31 Jul 2019  路  5Comments  路  Source: graphql-nexus/nexus-plugin-prisma

When using the nexus-prisma plugin with Prisma 1, as pointed out in the plugin's docs, it's possible to expose all types with all fields and crud operations, without needing to list each and every one of them, for example (taken from the docs):

const Query = prismaObjectType({
  name: "Query",
  definition: (t) => t.prismaFields(["*"]),
});

The @prisma/nexus plugin for Prisma2 does not currently have this functionality. I was advised in the #prisma2-preview slack channel to open an issue to request such of a feature.

For now I've created a slight work-around:

const allTheThings = obj => {
  for (const method in obj) {
    if (typeof obj[method] === "function") {
      obj[method]();
    }
  }
}

// ...

const Person = objectType({
  name: "Person",
  definition(t) {
    allTheThings(t.model);
  },
});
notduplicate scopprojecting typfeat

Most helpful comment

@jmadson, i have been using your experiment for practice until the prisma and nexus officially resolves this. Maybe we can convert this into a npm package which will auto read the schema.prisma file and get the types.

Workflow:

  • change the schema.prisma
  • run yarn prisma generate
  • run node generate.js => which runs the following script

Generator code

const {
  makeSchema,
  queryType,
  mutationType,
  objectType,
} = require("@nexus/schema");
const { nexusSchemaPrisma } = require("nexus-plugin-prisma/schema");
const { PrismaClient } = require("@prisma/client");
const prisma = new PrismaClient();

// https://github.com/graphql-nexus/nexus-schema-plugin-prisma/issues/339
const allTheThings = (obj) => {
  for (const method in obj) {
    if (typeof obj[method] === "function") {
      obj[method]();
    }
  }
};

// extract all models from prisma dmmf
const parentTypes = () => {
  const models = prisma._dmmf.mappings.map((e) => e.model);
  return models.map((name) =>
    objectType({
      name,
      definition(t) {
        allTheThings(t.model);
      },
    })
  );
};

makeSchema({
  // Where to export the data
  outputs: {
    schema: __dirname + "/generated/nexus.graphql",
    typegen: __dirname + "/generated/nexus.ts",
  },
  // all the types to expose
  types: [
    queryType({
      definition(t) {
        allTheThings(t.crud);
      },
    }),
    mutationType({
      definition(t) {
        allTheThings(t.crud);
      },
    }),
    ...parentTypes()
  ],
  // just few stuff to make this workaround work
  typegenAutoConfig: {
    contextType: "{ prisma: PrismaClient.PrismaClient }",
    sources: [{ source: "@prisma/client", alias: "PrismaClient" }],
  },
  plugins: [nexusSchemaPrisma({experimentalCRUD: true, shouldGenerateArtifacts: true})],
});

Then it worked just as before, like all tutorials in the world exists for prisma1,

schema.graphql

# import * from './generated/nexus.graphql'

type Query {
  texts: [Text!]!
  text(id: ID!): Text
}

index.js

const { GraphQLServer } = require("graphql-yoga");
const { PrismaClient } = require("@prisma/client");
const prisma = new PrismaClient();

const resolvers = {
  Query: {
    texts: (_, {}, context) => context.prisma.text.findMany(),
  },
};

const server = new GraphQLServer({
  typeDefs: __dirname + "/schema.graphql",
  resolvers,
  context: { prisma },
});
server.start(() => console.log("Server is running on localhost:4000"));

All 5 comments

Hey 馃憢,

This is a duplicate of #299. Closing now

@jmadson, i have been using your experiment for practice until the prisma and nexus officially resolves this. Maybe we can convert this into a npm package which will auto read the schema.prisma file and get the types.

Workflow:

  • change the schema.prisma
  • run yarn prisma generate
  • run node generate.js => which runs the following script

Generator code

const {
  makeSchema,
  queryType,
  mutationType,
  objectType,
} = require("@nexus/schema");
const { nexusSchemaPrisma } = require("nexus-plugin-prisma/schema");
const { PrismaClient } = require("@prisma/client");
const prisma = new PrismaClient();

// https://github.com/graphql-nexus/nexus-schema-plugin-prisma/issues/339
const allTheThings = (obj) => {
  for (const method in obj) {
    if (typeof obj[method] === "function") {
      obj[method]();
    }
  }
};

// extract all models from prisma dmmf
const parentTypes = () => {
  const models = prisma._dmmf.mappings.map((e) => e.model);
  return models.map((name) =>
    objectType({
      name,
      definition(t) {
        allTheThings(t.model);
      },
    })
  );
};

makeSchema({
  // Where to export the data
  outputs: {
    schema: __dirname + "/generated/nexus.graphql",
    typegen: __dirname + "/generated/nexus.ts",
  },
  // all the types to expose
  types: [
    queryType({
      definition(t) {
        allTheThings(t.crud);
      },
    }),
    mutationType({
      definition(t) {
        allTheThings(t.crud);
      },
    }),
    ...parentTypes()
  ],
  // just few stuff to make this workaround work
  typegenAutoConfig: {
    contextType: "{ prisma: PrismaClient.PrismaClient }",
    sources: [{ source: "@prisma/client", alias: "PrismaClient" }],
  },
  plugins: [nexusSchemaPrisma({experimentalCRUD: true, shouldGenerateArtifacts: true})],
});

Then it worked just as before, like all tutorials in the world exists for prisma1,

schema.graphql

# import * from './generated/nexus.graphql'

type Query {
  texts: [Text!]!
  text(id: ID!): Text
}

index.js

const { GraphQLServer } = require("graphql-yoga");
const { PrismaClient } = require("@prisma/client");
const prisma = new PrismaClient();

const resolvers = {
  Query: {
    texts: (_, {}, context) => context.prisma.text.findMany(),
  },
};

const server = new GraphQLServer({
  typeDefs: __dirname + "/schema.graphql",
  resolvers,
  context: { prisma },
});
server.start(() => console.log("Server is running on localhost:4000"));

@entrptaher - Good idea. Feel free to introduce a helper npm package as you mentioned. Also, consider commenting it in #299 which relates to this post.

On a side note, our team no longer exposes each and every field automatically. While it's nice for early prototyping an idea, I'm concerned that it could introduce a security risk by exposing fields and operations we otherwise would not intentionally expose.

The generator code I wrote here also expired and needs some adjustment to work with the latest nexus versions. I see how this is going to be a maintenance issue.

I created a helper npm package with the code for prisma 2.10.0.
https://github.com/entrptaher/prisma-schema-to-graphql

Was this page helpful?
0 / 5 - 0 ratings