= Schemas :description: Refuse a document that does not match: write a JSON Schema once, bind it to a collection, and every write from every client is validated on the server. :keywords: JSON Schema validation, document validation, MongoDB schema, data model, required fields, input validation backend :group: Your data :order: 50 A schema says what a document must look like: which fields, of which type, which are required, which values are allowed. Bind one to a collection and every `POST`, `PUT` and `PATCH` is checked on the server before it is stored, whoever sends it. Your app can still validate forms for a better error message; it no longer has to, for the data to stay clean. Schemas are JSON Schema draft-07, stored in the `_schemas` collection and managed under **Schemas**. image::/assets/docs-images/schemas.png[The Schemas page: each schema with its type, the number of properties and required fields] == Write a schema Click **Create Schema**, choose an `_id` and paste the schema. This one validates a product: [source,json] ---- { "_id": "product", "title": "Product", "description": "A product of the catalog", "$schema": "http://json-schema.org/draft-07/schema#", "type": "object", "properties": { "name": { "type": "string", "minLength": 1 }, "price": { "type": "number", "minimum": 0 }, "category": { "type": "string", "enum": ["electronics", "clothing", "food"] }, "inStock": { "type": "boolean" } }, "required": ["name", "price", "category"] } ---- The `_id` is how you will refer to it. `title` and `description` show in the list. The rest is JSON Schema; these are the keywords you will use most: [cols="1,3"] |=== | Keyword | What it does | `type` | `string`, `number`, `integer`, `boolean`, `object`, `array`, `null`. | `properties` and `required` | The fields, and which of them must be present. | `enum` | The only values allowed. | `minimum`, `maximum`, `minLength`, `maxLength`, `pattern` | Ranges, lengths, and a regular expression for strings. | `items` | The schema of each element of an array. | `additionalProperties: false` | Refuse fields that are not in `properties`. | `if`, `then`, `else` | A rule that depends on another field. |=== **Setup BSON Types** adds a schema that describes MongoDB's own types, so yours can say a field is a date with `{"$ref": "bson#/date"}` rather than a string. Declare a date field as `{"_$date": {"type": "number"}}` when a permission fills it with `@now`. The editor checks the JSON as you type. The full vocabulary is in the https://json-schema.org/specification-links#draft-7[JSON Schema draft-07 specification]. == Bind it to a collection A schema does nothing until a collection uses it. On the **Collections** page, open the collection's metadata with the gear, choose the schema under **JSON Schema Validator**, and save. When you create a collection, you can pick the schema there. One schema can serve several collections. Editing it affects all of them, for writes from then on: documents already stored are not checked again. == What your app sees A document that does not match is refused with `400 Bad Request` and a body that says why: [source,json] ---- { "http status code": 400, "message": "Document validation failed", "exception": { "message": "required key [customerId] not found" } } ---- Show that message to the user, or map it to your form. A `PATCH` is validated on the document as it would be after the change, so a partial update cannot leave a document invalid. == From a script [cols="2,3"] |=== | Operation | API | List | `GET /_schemas` | Create | `POST /_schemas` with the schema as the body | Update | `PATCH /_schemas/` | Delete | `DELETE /_schemas/` | Bind to a collection | `PATCH /` with `{ "jsonSchema": { "schemaId": "" } }` |=== Deleting a schema does not unbind it: a collection that still references it refuses every write until you bind another or remove the reference. With xref:cli.adoc[`rhc`], schemas and their bindings are part of the setup file. == Related pages * xref:constraints.adoc[Constraints]: rules across documents, which a schema cannot express. * xref:managing-indexes.adoc[Indexes]: a unique index, for a field that must not repeat. * xref:managing-data.adoc[Collections and documents]: where the schema is bound. * link:{restheart-docs}/mongodb-rest/json-schema-validation[JSON Schema validation reference] on restheart.org.