valentinpalkovic/prisma-json-schema-generator

ignoreRelatedModels (but include foreign key fields)

Opened this issue ยท 6 comments

Great work on this!

I was thinking of using a generated schema as a starting point for user input validation.
In most cases, I would have no use for the relations.

model agedivision {
  id                  Int                   @id @default(autoincrement())
  ageDivName          String               @db.VarChar(30)
  agedivision_athlete agedivision_athlete[]
  athlete             athlete[]
}

Currently produces:

{
  "agedivision": {
    "type": "object",
    "properties": {
      "id": {
        "type": "integer"
      },
      "name": {
        "type": "string"
      },
      "agedivision_athlete": {
        "type": "array",
        "items": {
          "$ref": "#/definitions/agedivision_athlete"
        }
      },
      "athlete": {
        "type": "array",
        "items": {
          "$ref": "#/definitions/athlete"
        }
      }
    }
  }
}

I would have liked:

{
  "agedivision": {
    "type": "object",
    "properties": {
      "id": {
        "type": "integer"
      },
      "name": {
        "type": "string"
      }
    }
  }
}

Foreign keys would be included.

Is this a feature that you have plans for?

I also really need this.
My usecase: I want to generate Mongo $jsonSchema out of Prisma schema.

@Flax95 Thank you for opening up this issue!

Should the relations only be dropped, If they are not available in the schema or always?

Always.


Let me take the opportunity to further explain my use case:

I am working on an Express REST api.
In my project I divided the different parts of my API into modules. My user module looks like this:
image

.routes contains routes where, if needed, a validator is called as middleware.
After the validator ran (and if no validation/parsing errors where thrown), the controller calls a service that interacts with prisma.

user.routes.js example:

  import userValidators from './user.validation';
  ...
  userRouter.post('/', userValidators.createUser, createUser);

  userRouter.get('/', getAllUsers);

user.validation.js example:

import { createUserSchema } from './schemas';
import { validateJsonSchema } from '../../utils/validation.util';

const createUser = (req, res, next) => {
  const user = {
    ...req.body,
    userRoleId: parseInt(req.body.userRoleId, 10),
  };

  validateJsonSchema(createUserSchema, user);

  req.body.user = user;
  next();
};

const userValidators = {
  createUser,
};

export default userValidators;

createUserSchema.json example:

{
  "type": "object",
  "properties": {
    "firstName": { "type": "string" },
    "lastName": { "type": "string" },
    "email": { "type": "string", "format": "email" },
    "password": { "type": "string", "minLength": 8 },
    "userRoleId": { "type": "integer", "minimum": 1 }
  },
  "additionalProperties": false,
  "required": ["firstName", "lastName", "email", "password", "userRoleId"]
}

validateJsonSchema(schema, data) is using the Ajv schema validator to validate an object of user inputs against a JSON schema.

What I wish to do is generate something as close to createUserSchema as possible.
Currently the JSON schema generated from my Prisma schema contains userRole[] instead of userRoleId.

"user": {
      "type": "object",
      "properties": {
        "id": {
          "type": "integer"
        },
        "firstName": {
          "type": ["string", "null"]
        },
        "lastName": {
          "type": ["string", "null"]
        },
        "email": {
          "type": ["string", "null"]
        },
        "password": {
          "type": ["string", "null"]
        },
        "userRole": {
          "anyOf": [
            {
              "$ref": "#/definitions/userRole"
            },
            {
              "type": "null"
            }
          ]
        }
      }
    },

You are already able to also generate the relational scalar fields by enabling it in the settings:

generator jsonSchema {
  provider = "prisma-json-schema-generator"
  keepRelationScalarFields = "true"
}

Then userRoleId will be generated as well. And the only feature you would like to have is to ditch the relation fields. Am I right?

Correct.


Edit:
I am clearly having problems explaining myself in plain English this week, my apologies. ๐Ÿ˜…

I actually ended up forking your plugin to make it produce the output suitable for Mongo $jsonSchema. Will publish it later (giving the credit of course).