Skip to main content

Lesson 1. Basic concepts

Example 1.1. The simplest project

JSIGHT 0.3

GET /cats

A project is a file (or several files) that describes a REST API in the JSight language. The *.jst extension is commonly used for such files.

The given example shows the code for the simplest project you can imagine.

Line 1 indicates the language version of this project (0.3) using the directive JSIGHT. Any project should start with this directive to ensure that parsers always know which version of the JSight language they are dealing with.

Line 3 specifies the directive GET as well as one of the parameters of this directive — /cats. This construct indicates that our REST API has the resource /cats that can be accessed using the method GET.

Example 1.2. The simplest schema

JSIGHT 0.3

GET /cats/{id}
200
{
"id" : 123,
"name": "Tom"
}

In this example, we have made our project a little more complicated.

First, we changed the path to our resource from /cats to /cats/{id} on line 3. This means that we can make GET requests for addresses that match this new pattern, for example, GET /cats/1 or GET /cats/123, or even GET /cats/Tom.

Secondly, we added one more directive 200 (line 4). This directive indicates that an HTTP code 200 can be received in response to a GET request. The schema of this response is described in lines 5–8 below.

A schema is used to describe the data structures of your API. Schemas can be described using different notations — that is, different data description languages. By default, the JSight API language uses the JSight notation of the same name to describe schemas. This is the notation used on lines 5–8 of our example.

IMPORTANT

The main principle of the schema of JSight notation is:

THE SCHEMA IS BASED ON AN EXAMPLE OF VALID DATA.
 

An example of valid data in itself already sets some obvious data requirements. Specifically: the example specifies the requirements for the types and the data structure.

info

For more information about requirements which are set by the example of valid data, see:

Lines 5–8 in our example show an example of valid data that is expected in the response body. This schema literally makes the following intuitive data requirements:

  1. The root data element must be an object.
  2. The root object must contain two mandatory fields: "id" and "name".
  3. The value of the field "id" must be of the type integer.
  4. The value of the field "name" must be of the type string.

For example, the following data will correspond to the given schema:

{
"id" : 123125894,
"name": "Marmalade"
}

Here is an example of data that does NOT correspond to the given schema:

{
"id" : "123", # --ERROR! The type `integer` is expected.
"name": "Marmalade"
}

Example 1.3. Schema with rules

JSIGHT 0.3

GET /cats/{id}
200
{
"id" : 123, // {min: 1}
"name" : "Tom", // {maxLength: 120}
"size" : "XL", // {enum: ["S", "M", "L", "XL"]}
"email": "tom@cats.com" // {type: "email", optional: true}
}

In this example, we have slightly increased the complexity of the response schema with the code 200 to the request GET /cats/{id}.

Our schema (lines 5–10) now includes not only an example of valid data, but also additional requirements that cannot be determined from an example of valid data. These additional requirements are referred to as rules. Rules are placed in so-called annotations. Annotations are similar to C-style comments.

In the given schema, several rules are specified that set the following additional data requirements:

  1. The value in the field "id" must be greater than zero (line 6).
  2. The value in the field "name" can not be longer than 120 characters (line 7).
  3. The value in the field "size" must correspond to one of the enumeration elements: "S", "M", "L", "XL" (line 8).
  4. The value in the field "email" must correspond to the type email (line 9, rule type).
  5. Field "email" is not required (line 9, rule optional).
info

For more information about this topic, see:

Example 1.4. Directive

JSIGHT 0.3

GET /cats/{id} // Get a cat by its id.

200 // Returns the data of the cat.
{
"id" : 123,
"name": "Tom"
}

In this example, we added annotations to the directive GET and directive 200. In the previous example, we placed schema rules in the annotations; in this example we can see that text notes can also be placed in the annotations.

Using the previous example, we can now define the term “directive”.

The directive is the main syntactic construct of the JSight language. The project consists entirely of directives.

The directive consists of four parts:

  1. Keyword of the directive. There are three directives in our example with the keywords JSIGHT, GET and 200. The keyword always starts with a new string.
  2. Parameters of the directive. Placed immediately after the keyword. Separated by spaces, can be enclosed in quotes. In our example, the directive JSIGHT has one parameter 0.3, the directive GET has one parameter /cats/{id}, and the directive 200 has no parameters.
  3. Annotation of the directive. It is written immediately after the directive parameters and contains a brief textual description of the directive. In our example, annotations are specified for the directives GET and 200.
  4. The body of the directive. If the directive has a body, it begins on the next line after the directive keyword. There are directives that do not have a body, such as the directive JSIGHT (line 1). The body of a directive can contain a variety of content, such as a schema or other child directives. In our example, the directive JSIGHT has no body; the directive GET has a body that contains entirely of child directive 200 (lines 4–9); and the directive 200 has a body that contains the data schema (lines 6–9).
note

Line indentation has no meaning in the JSight language. Context, not indentation size, defines child directives. In the given examples, child directives are highlighted by increasing the indentation only for readability.