question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Include "required" and "additionalProperties" keys to the object definitions

See original GitHub issue

Feature Request

Include “required” and “additionalProperties” keys to the object definitions. The field list of “required” key should be as per the prisma model definition. The “required” is very much needed as the default behaviour of json schema specs is to allow empty objects to pass the validation. For example:

{
  "definitions": {
    "address": {
      "type": "object",
      "properties": {
        "street_address": { "type": "string" },
        "city":           { "type": "string" },
        "state":          { "type": "string" }
      },
      "required": ["street_address", "city", "state"]
    }
  },
  "additionalProperties": false
}

Issue Analytics

  • State:closed
  • Created 3 years ago
  • Reactions:5
  • Comments:9 (4 by maintainers)

github_iconTop GitHub Comments

2reactions
auderercommented, Apr 24, 2021

Here’s my solution to this problem, a simple utility function:

export const requireSchema = <T>(
    schema: { type: string; properties: T },
    required: (keyof T)[]
) => {
    return { ...schema, required }
}

It takes a schema definition with a list of required params. Here’s an example using it with fastify:

server.route<{ Body: Lead }>({
    method: "POST",
    url: "/leads",
    schema: {
        body: requireSchema(schema.definitions.Lead, [
            "first_name",
            "last_name",
            "email",
        ]),
    },
    handler: async (req, reply) => {
        // ...
    },
})

This allows to enforce which fields are necessary on a route-by-route basis instead of just based on the database. Since it makes use of typescript generics, the array of required fields is validated against the schema, so its type-safe. With this method you could make the mistake of leaving out a field required by the database, but at that point Prisma will throw an error anyway. For me this is a decent middle-ground.

0reactions
valentinpalkoviccommented, Jan 15, 2022

This library isn’t usable without required

I think we have to talk about the abilities of the Prisma schema and its main purpose.

Per docs, the Prisma schema consists of three parts:

Data sources: Specify the details of the data sources Prisma should connect to (e.g. a PostgreSQL database)

Generators: Specifies what clients should be generated based on the data model (e.g. Prisma Client)

Data model definition: Specifies your application models (the shape of the data per data source) and their relations

The Prisma model definitions “represent the entities of your application domain, map to the tables (relational databases like PostgreSQL) or collections (MongoDB) in your database, form the foundation of the queries available in the generated Prisma Client API and when used with TypeScript, Prisma Client provides generated type definitions for your models and any variations of them to make database access entirely type-safe.” - https://www.prisma.io/docs/concepts/components/prisma-schema/data-model

By only parsing the Prisma model, it is not possible to figure out, which endpoints will be created, whether it is a GraphQL endpoint or a plain REST endpoint. The actual code of your backend defines, which data the user has to send to create, read, update or delete data. Already mentioned techniques like computed fields makes things even more unpredictable. It would be necessary to parse your endpoints to create JSON schema definitions for each of them.

As @auderer already mentioned, you need validation on a route-by-route base, instead of purely relying on the type definition of the database models. The generated JSON schema can help you, but currently, it’s still your responsibility to set the “required” flag on a route-by-route base.

Let’s take a look, what would happen if all the fields would be marked as required:

Read

Depending on where the schema validation happens, it can cause huge problems, if all the fields are marked as required (except the fields which have the attributes @id, @default or @updatedAt). Talking about GraphQL, the client is able to fetch only a subset of a specific model, which is required for a specific purpose. Talking about REST, you might create REST endpoints, which will only deliver a subset of the defined model to the client.

Update

Updating a model can happen in a lot of different ways. The client might send only a subset of data (patch, a partial update) or it has to update all of the fields at once (put operation). The Prisma model doesn’t define this behaviour, but your programming code does. It’s impossible to guess, whether all the fields are required or only a subset without analyzing your endpoints.

Create

Creating a new entry in your database requires all the field information for a model. But it doesn’t mean, that all the defined model fields have to be sent by the client. Maybe some information is aggregated or fetched from a different source. This means, that the client might only send a subset of the needed information and the rest is calculated/aggregated/pulled from another source.

As you can see, it is not possible to just mark all the fields as required, because a couple of cases are not covered.

@ShivamJoker Nevertheless, if you have some smart ideas to tackle the mentioned issues, I would be happy to continue the discussion and maybe find a way of supporting your needed use case. Maybe you can start by describing your issue in detail with some examples to continue the discussion upon it.

Read more comments on GitHub >

github_iconTop Results From Across the Web

object — Understanding JSON Schema 2020-12 documentation
Unevaluated Properties; Required Properties; Property names; Size. Objects are the mapping type in JSON. They map “keys” to “values”. In JSON, the “keys” ......
Read more >
Make it clear that additionalProperties can only have ... - GitHub
JSON Schema allows for additionalProperties both a boolean or an object value. true is interpreted as "additional properties follow no ...
Read more >
Additional Properties - Liquid Technologies
The value of "additionalProperties" MUST be a boolean or an object. If it is an object, it MUST also be a valid JSON...
Read more >
Why `additionalProperties` is the way to represent Dictionary ...
to validate properties that are not known. For clarity: The property names, or "keys" in the map, must be strings.
Read more >
Objects - JSON Schema
JSON Schema contains several keywords allowing us to define more specific types of ... Specifies documents that need to have pairs with key...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found