This is the format for specifying your web service to jsvcgen
.
It is JSON-based and uses a mix of concepts from json-schema, JSON-WSP and
Swagger.
The file extension is simply .json
.
Because JSON-RPC does not need to be run over HTTP, there is not any support for using different
HTTP methods.
The only HTTP verb JSON-RPC uses is POST
.
JSON-RPC has a system of rich error notifications, which means there is no explicit need for HTTP status codes.
However, when running JSON-RPC over HTTP, it is generally considered best practice to use 200
to indicated success and
some other form of an error code (in the 4xx
or 5xx
range) to indicate an error to the client.
The full list of status codes can be seen at RFC 2616.
The official MIME type is "application/json+jsvcgen-description"
, but "application/json"
is perfectly fine.
Common Name | JSON Type | jsvcgen Type |
Comments |
---|---|---|---|
float | number |
float |
|
double | number |
float |
|
number | number |
number |
|
integer | number |
integer |
JSON only supports floating-point, so this is a restriction. |
string | string |
string |
|
boolean | boolean |
boolean |
|
array | array |
["${type}"] |
Arrays are uniform. Use an alias to restrict lengths. |
The order of arrays specifying things like "members"
of a type definition, "params"
of a
method, "types"
of a service description and so on matters only a little.
When using a code or documentation generator, the output order is typically the same as the input, so the order you
define your parameters in the JSON document will end up the same in your Java output.
For each description object, you are allowed to add any extra fields you want and they will simply be ignored.
However, for future-proofing your description files, it is a good idea to prefix your custom fields with x-
.
The contents of any extension fields are unchecked and can be any valid JSON value.
The root of a jsvcgen
document is the ServiceDescription
.
Field Name | Type | Description |
---|---|---|
"type" |
string |
Required. Should be "application/json+jsvcgen-description" . |
"servicename" |
string |
Required. The name of the service. This name is used in code generation. |
"host" |
string |
Required. Hostname of the service. This can be a pattern. |
"endpoint" |
string |
Required. Host-relative endpoint to connect to. This can be a pattern. |
"schemes" |
array[string] |
An array of supported URL schemes. Default value is ["http"] . |
"version" |
string |
The API version -- this is typically part of the URL. Default value is "1.0" . |
"documentation" |
Documentation |
Global documentation for the API. |
"types" |
array[ TypeDefinition ] |
Type definitions not necessarily tied with a particular method. Default value is [] . |
"methods" |
array[ Method ] |
List of methods this API provides. The default value is [] , but this is not very useful. |
{
"type": "application/json+jsvcgen-description",
"version": "1.2",
"servicename": "UserService",
"host": "${kerberosHost}",
"endpoint": "/json-rpc/${version}/",
"schemes": [ "https" ],
"documentation": [
"An API for controlling Kerberos users and groups."
],
"types": [ ... ],
"methods": [ ... ]
}
Documentation fields can be found on almost all types of description objects. The purpose is to provide users with some description of what a method does, what a type represents, what a parameter or member means and so on. You should provide useful documentation -- your users will thank you.
A documentation object can be either a string
or an array of string
s.
There is no particular meaning associated with a single break in the string, so you can think of the strings being
joined back together by placing a single space (" "
) between them.
If there is a blank line in the documentation array, it is treated as the start of a new paragraph.
[
"Complex documentation can be split into an array for ease of maintenance.",
"You can break it up however you want.",
"",
"Leave a blank \"line\" to start a new paragraph."
]
A member is used inside of a type definition to describe specific elements of a structure.
The "name"
will be the key in the structure, the "type"
describes the value.
Field Name | Type | Description |
---|---|---|
"name" |
string |
Required. The name of this member. It is expected (but not required) to be ^[a-zA-Z_][a-zA-Z_0-9]*$ . |
"type" |
TypeUse |
Required. The type of this member. |
"documentation" |
Documentation |
Documentation for this member. |
"members": [
{ "name": "username", "type": "string" },
{ "name": "user_id", "type": "UserID" },
{
"name": "mobile",
"type": "PhoneNumber",
"documentation": ["A mobile phone number for the user."]
},
{ "name": "age", "type": "number" },
{ "name": "given_name", "type": "string" },
{ "name": "surname", "type": "string" }
]
A method describes an operation the service can provide.
The value of "name"
will be used as the "method"
in the JSON-RPC request.
Field Name | Type | Description |
---|---|---|
"name" |
string |
Required. The name of this method. It is expected (but not required) to be ^[a-zA-Z_][a-zA-Z_0-9]*$ . |
"documentation" |
Documentation |
Documentation for this method. |
"params" |
array[ TypeUse ] |
An array of parameters this method accepts. By default, the method will accept no parameters ({} ). |
"returnInfo" |
ReturnInfo |
Information about the result of calling this method. By default, the method does not return information (void ). |
Allows for refinement of an alias by restricting its values by certain criteria.
All fields are optional, meaning the default value of {}
is an unrestricted type.
The names and meanings of the restrictions are taken from json-schema
Field Name | Type | Description |
---|---|---|
"maximum" |
number |
The maximum value for a number. |
"exclusiveMaximum" |
boolean |
Is the "maximum" value exclusive? |
"minimum" |
number |
The minimum value for a number. |
"exclusiveMinimum" |
boolean |
Is the "minimum" value exclusive? |
"maxLength" |
integer |
The maximum length of a string . |
"minLength" |
integer |
The minimum length of a string . |
"maxItems" |
integer |
The maximum length of an array. |
"minItems" |
integer |
The minimum length of an array. |
"uniqueItems" |
boolean |
Do the elements of an array have to be unique? |
"enum" |
array[ EnumSpecification ] |
Should the elements of the array be restricted to certain values? |
"multipleOf" |
number |
Does a number have to be a multiple of something? |
The upper limit for a numeric value.
The field "exclusiveMaximum"
only applies if "maximum"
is present.
If "exclusiveMaximum"
is false
, the value is allowed to include the value specified in "maximum"
.
The default value for "exclusiveMaximum"
is false
, meaning the default behavior is inclusive.
"restriction": {
"maximum": 10,
"exclusiveMaximum": true
}
The lower limit for a numeric value.
The field "exclusiveMinimum"
only applies if "minimum"
is present.
If "exclusiveMinimum"
is false
, the value is allowed to include the value specified in "minimum"
.
The default value for "exclusiveMinimum"
is false
, meaning the default behavior is inclusive.
"restriction": {
"minimum": 0,
"exclusiveMinimum": false
}
The minimum and maximum length of a string
(for arrays, see "minItems"
and
"maxItems"
.
Both numbers must be greater than or equal to 0.
It is highly recommended that "minLength"
be less than or equal to "maxLength"
, but this is not required.
"restriction": {
"minLength": 8,
"maxLength": 20
}
A regular expression to restrict the string value by.
This restriction is only valid on string
s.
The supported regex syntax is ECMAScript.
"restriction": {
"pattern": "^[A-Z][a-z]+$"
}
The minimum and maximum length of an array (for string
s, see "minLength"
and
"maxLength"
.
Both numbers must be greater than or equal to 0.
It is highly recommended that "minItems"
be less than or equal to "maxItems"
, but this is not required.
"restriction": {
"minItems": 3,
"maxItems": 15
}
For an array, do the items in the array have to be unique?
By default, this is false
.
Restricts a type to a specific subset of possible values.
This is typically used on string
types, but can be applied to any other type.
Field Name | Type | Description |
---|---|---|
"value" |
any | Required. An allowed value -- should be the same type as what the type definition is aliasing. |
"documentation" |
Documentation |
Documentation about this value. |
If you do not wish to include documentation for your values, you can forgo the object wrapper and use the value for
"value"
directly in the array.
This is not allowed if your value type is an object itself.
"restriction": {
"enum": [
{
"value": "apple",
"documentation": "An apple is the pomaceous fruit of the apple tree."
},
{
"value": "banana",
"documentation": "A yellow fruit made in a factory."
},
{
"value": "crayon",
"documentation": "A delicious, healthy snack."
}
]
}
Shorthand without documentation:
"restriction": {
"enum": ["apple", "banana", "crayon"]
}
Restrict a numeric value to be a multiple of some other number.
"restriction": {
"multipleOf": 5
}
Describes the result of calling a method.
Field Name | Type | Description |
---|---|---|
"type" |
TypeUse |
Required. The type this method returns. |
"documentation" |
Documentation |
Documentation about what this method returns. |
{
"type": ["string"],
"documentation": "The list of groups the user is a member of."
}
A TypeDefinition
is a free-floating type not necessarily associated with a method, but are referred to by
methods.
There are two major kinds of definitions: a structure and an alias.
A structure defines a JSON object with a list of members.
An alias allows you to refer to another type via a different name and allows refinement of that type through a
restriction.
Field Name | Type | Description |
---|---|---|
"name" |
string |
Required. The name of this type. It will be referred to in other places by name. It is expected (but not required) to be [a-zA-Z_][a-zA-Z_0-9]* . |
"members" |
array[ Member ] |
Required for structures. A list of members for this structure. |
"alias" |
TypeUse |
Required for aliases. The type to alias. |
"restriction" |
Restriction |
When this is an alias, refine values by this criteria. |
"documentation" |
Documentation |
Type-level documentation. |
A structure:
{
"name": "User",
"documentation": [
"A user is a system contact.",
"They are probably a real person, but might be a robot.",
"You never know these days."
],
"members": [
{ "name": "username", "type": "string" },
{ "name": "user_id", "type": "UserID" },
{
"name": "mobile",
"type": "PhoneNumber",
"documentation": ["A mobile phone number for the user."]
},
{ "name": "age", "type": "number" },
{ "name": "given_name", "type": "string" },
{ "name": "surname", "type": "string" }
]
}
An alias:
{
"name": "PhoneNumber",
"alias": "string",
"restriction": {
"pattern": "[0-9]{3}-[0-9]{3}-[0-9]{4}"
}
}
Field Name | Type | Description |
---|---|---|
"name" |
string or array[string] |
Required. The name of the type -- refers to a type definition. |
"optional" |
boolean |
Is this parameter or member optional? By default, this is false . |
To simply specify a type (integer
):
"integer"
An array of integer
s:
["integer"]
An optional integer
:
{ "name": "integer", "optional": true }
An optional array of integer
s:
{ "name": ["integer"], "optional": true }