KrekkieD
KrekkieD

Reputation: 1017

How do I set up my json schema structure

I'm trying to figure out how a json schema should be implemented (as standardized as possible).

I have noticed that if I define a schema for a form using the v4 draft, I cannot voice the requirements my project has. So I created a schema that uses the v4 schema ("$schema": "http://json-schema.org/draft-04/schema#"), and gave it a custom id for the project, lets call it projectschema#. This schema validates, so all is good standard-wise. I have added two values to the type enum.

I then use this schema as $schema for another schema that describes form properties and validations, the formschema#. This schema too validates, this time against the projectschema#.

Now, as documented on www.json-schema.org, there's also a hyper-schema which allows the definition of links. Useful, as I can define where to POST the form to, or even where to get valueSets to use in the form (i.e. a rest service to get a list of user titles).

However, the v4 schema itself does not support links. I see how the v4 hyper-schema draft does support links, and is referencing the v4 schema draft, but I cannot figure out how to implement the hyper-schema, which probably means I'm missing some fundamental part of the 'how to use and implement json schema' knowledge.

I found the following on http://json-schema.org/latest/json-schema-hypermedia.html:

JSON Schema is a JSON based format for defining the structure of JSON data. This document specifies hyperlink- and hypermedia-related keywords of JSON Schema.

The term JSON Hyper-Schema is used to refer to a JSON Schema that uses these keywords.

If the draft hyper-schema uses the draft schema keywords, then why is the 'links' keyword nowhere to be found in the schema?

Is my (or any) custom schema actually a hyper schema? And if so, is anything that implements a (custom or draft) json schema called a hyper schema?

I could fire off a hundred questions. Main question: what is the relation between a Schema and a Hyper Schema, and how should I implement a schema for a form that needs more types than defined in the v4 draft?

Upvotes: 2

Views: 3476

Answers (2)

Mark Paine
Mark Paine

Reputation: 1894

Sorry for the length of this answer. Hopefully it's helpful.

I too struggled to understand how to validate a particular link in Hyper-Schema so I implemented each link as a base JSON Schema then tied each link together with a Hyper-Schema.

Definitions (definitions.json):

{
  "$schema" : "http://json-schema.org/schema#",

  "definitions" : {
    "id" : {
      "type" : "integer",
      "minimum" : 1,
      "exclusiveMinimum" : false
    },

    "foreign_key_id" : {
      "$ref" : "#/definitions/id"
    },

    "season_name" : {
      "type" : "string",
      "minLength" : 1,
      "maxLength" : 1,
      "pattern" : "^[A-T]{1,1}$"
    },

    "currency" : {
      "type" : "integer"
    },

    "shares" : {
      "type" : "integer"
    },

    "username" : {
      "type" : "string",
      "minLength" : 1,
      "maxLength" : 19,
      "pattern" : "^[^ ]{1,19}$"
    },

    "name" : {
      "type" : "string",
      "minLength" : 1,
      "maxLength" : 64,
      "pattern" : "^[A-Za-z0-9][A-Za-z0-9_\\- ]*$"
    },

    "email" : {
      "type" : "string",
      "format" : "email"
    },

    "timestamp" : {
      "type" : "string",
      "format" : "date-time"
    }
  }
}

Base object schema:

{
  "$schema" : "http://json-schema.org/schema#",

  "type" : "object",

  "properties" : {
    "id" : { "$ref" : "definitions.json#/definitions/id" },
    "season_name" : { "$ref" : "definitions.json#/definitions/season_name" },
    "user_id" : { "$ref" : "definitions.json#/definitions/foreign_key_id" },
    "coins" : { "$ref" : "definitions.json#/definitions/currency" },
    "bonus_coins" : { "$ref" : "definitions.json#/definitions/currency" },
    "created_at" : { "$ref" : "definitions.json#/definitions/timestamp" },
    "updated_at" : { "$ref" : "definitions.json#/definitions/timestamp" }
  },

  "required" : [
    "id",
    "season_name",
    "user_id",
    "coins",
    "bonus_coins",
    "created_at",
    "updated_at"
  ],

  "additionalProperties" : false
}

POST schema (account_request_post.json):

{
  "$schema" : "http://json-schema.org/schema#",

  "type" : "object",

  "properties" : {
    "season_name" : { "$ref" : "definitions.json#/definitions/season_name" },
    "user_id" : { "$ref" : "definitions.json#/definitions/foreign_key_id" }
  },

  "required" : [
    "season_name",
    "user_id"
  ],

  "additionalProperties" : false
}

Hyper Schema:

{
  "$schema" : "http://json-schema.org/schema#",

  "type" : "object",

  "links" : [
    {
      "description" : "Create a new account.",
      "href" : "accounts",
      "method" : "POST",
      "rel" : "create",
      "title" : "Create",
      "schema" : { "$ref" : "account_request_post.json#" }
    },

    {
      "description" : "List accounts.",
      "href" : "accounts",
      "method" : "GET",
      "rel" : "index",
      "title" : "List"
    }
  ]
}

Upvotes: 2

jruizaranguren
jruizaranguren

Reputation: 13597

Json hyper-schema is a subset of Json-schema standard dedicated to hyperlink and hypermedia keywords and rules.

The "links" keyword is defined in the hyper-schema section of the draft. Indeed it is a part of json-schema (despite it is defined in a special draft section)

If your are defining an API interface, it is likely you want to use hyper-schema. If you are just defining validation contracts, plain Json-schema keywords are enough.

Upvotes: 1

Related Questions