RESTful Service Description Language
Find sources: "RESTful Service Description Language" – news · newspapers · books · scholar · JSTOR (April 2015) (Learn how and when to remove this message)
Find sources: "RESTful Service Description Language" – news · newspapers · books · scholar · JSTOR (April 2015) (Learn how and when to remove this message)
The RESTful Service Description Language (RSDL) is a machine- and human-readable XML description of HTTP-based web applications (typically REST web services).[1]
The language (defined by Michael Pasternak during his work on oVirt RESTful API) allows documenting the model of the resource(s) provided by a service, the relationships between them, and operations and the parameters that must be supplied for the operations. It specifies whether parameters are mandated; and describes possible overloads as parameters sets.
RSDL is intended to simplify the reuse of web services that are based on the HTTP architecture of the web. It is platform- and language-independent and aims to promote reuse of applications beyond the basic use in a web browser by both humans and machines.
Unlike WADL, it concentrates on describing URIs as stand-alone entry points in to the application which can be invoked in different ways, does not require traversing over URI components to figure out URI structure, and supports URI/Headers/body parameters overloads. This makes it human-readable and easily consumed by both humans and machines.
Properties
[edit ]- Self descriptive: RSDL represents different URIs as stand-alone entry points into the application. Following resource URIs, one can figure out which methods are available for the given resources and how those resources can be consumed.
- Machine-readable: Each URI in RSDL contains all the necessary information to generate an HTTP request from it, which can be easily consumed by accessing the URI internals.
- Human-readable: Each URI in RSDL contains "rel" and "description" attributes describing the meaning of the given operation on that URI. Humans can easily fetch all available operations for a given collection/resource simply by locating different descriptors within the same URI.
Format
[edit ]<rsdlrel="rsdl"href="/api?rsdl"> <description/> <versionrevision="0"build="0"minor="0"major="0"/> <schemarel="schema"href="/api?schema"> <name>api.xsd</name> <description/> </schema> <generalrel="*"href="/*"> <request> <headers> <headerrequired="true|false"> <name/> <description/> <value/> </header> </headers> <url> <parameters_set> <parametercontext="query|matrix"type="xs:string" required="true|false"> <name/> <value/> </parameter> </parameters_set> </url> </request> <name/> <description/> </general> <links> <linkrel="get|..."href="/api/xxx"> <request> <http_method>GET|POST|PUT|DELETE|...</http_method> <headers> <headerrequired="true|false"> <name/> <value/> </header> </headers> <url> <parameters_set> <parametercontext="query|matrix"type="" required="true|false"> <name/> <value/> </parameter> </parameters_set> </url> <body> <type>...</type> <parameters_set> <parametertype=""required="true|false"> <name>FQ-name-to-parameter</name> </parameter> </parameters_set> </body> </request> <response> <type/> </response> </link> </links> </rsdl>
Components
[edit ]URI
[edit ]<links> <linkrel="get|..."href="/api/xxx">
Request
[edit ]<request> <http_method>GET|POST|PUT|DELETE|...</http_method> <headers> <headerrequired="true|false"> <name></name> <value></value> </header> ... </headers> <url> <parameters_set> <parametercontext="query|matrix"type=""required="true|false"> <name></name> <value></value> </parameter> ... </parameters_set> ... </url> <body> <type>...</type> <parameters_set> <parametertype=""required="true|false"> <name>FQ-name-to-parameter</name> </parameter> ... </parameters_set> ... </body> </request>
Response
[edit ]<response> <type></type> ... </response>
XML schema
[edit ]<xs:elementname="detailedLinks"type="DetailedLinks"/> <xs:complexTypename="DetailedLinks"> <xs:sequence> <xs:annotation> <xs:appinfo> <jaxb:propertyname="links"/> </xs:appinfo> </xs:annotation> <xs:elementtype="DetailedLink"name="link"maxOccurs="unbounded"/> </xs:sequence> </xs:complexType> <xs:elementname="link"type="Link"/> <xs:complexTypename="Link"> <xs:attributename="href"type="xs:string"/> <xs:attributename="rel"type="xs:string"/> </xs:complexType> <xs:elementname="url"type="Url"/> <xs:complexTypename="Url"> <xs:sequence> <xs:elementref="parameters_set"maxOccurs="unbounded"minOccurs="0"> <xs:annotation> <xs:appinfo> <jaxb:propertyname="ParametersSets"/> </xs:appinfo> </xs:annotation> </xs:element> </xs:sequence> </xs:complexType> <xs:elementname="body"type="Body"/> <xs:complexTypename="Body"> <xs:sequence> <xs:elementname="type"type="xs:string"minOccurs="1"maxOccurs="1"/> <xs:elementref="parameters_set"maxOccurs="unbounded"minOccurs="0"> <xs:annotation> <xs:appinfo> <jaxb:propertyname="ParametersSets"/> </xs:appinfo> </xs:annotation> </xs:element> </xs:sequence> <xs:attributename="required"type="xs:boolean"> <xs:annotation> <xs:appinfo> <jaxb:propertygenerateIsSetMethod="false"/> </xs:appinfo> </xs:annotation> </xs:attribute> </xs:complexType> <xs:elementname="request"type="Request"/> <xs:complexTypename="Request"> <xs:sequence> <xs:elementname="http_method"type="HttpMethod"minOccurs="1"maxOccurs="1"/> <xs:elementref="headers"minOccurs="0"maxOccurs="1"/> <xs:elementref="url"minOccurs="0"maxOccurs="1"/> <xs:elementref="body"minOccurs="0"maxOccurs="1"/> </xs:sequence> </xs:complexType> <xs:simpleTypename="HttpMethod"> <xs:restrictionbase="xs:string"> <xs:enumerationvalue="GET"/> <xs:enumerationvalue="POST"/> <xs:enumerationvalue="PUT"/> <xs:enumerationvalue="DELETE"/> <xs:enumerationvalue="OPTIONS"/> </xs:restriction> </xs:simpleType> <xs:elementname="response"type="Response"/> <xs:complexTypename="Response"> <xs:sequence> <xs:elementname="type"type="xs:string"minOccurs="1"maxOccurs="1"/> </xs:sequence> </xs:complexType> <xs:elementname="parameter"type="Parameter"/> <xs:complexTypename="Parameter"> <xs:complexContent> <xs:extensionbase="BaseResource"> <xs:sequence> <xs:elementname="value"type="xs:string"minOccurs="1"maxOccurs="1"/> <xs:elementref="parameters_set"minOccurs="0"maxOccurs="1"/> </xs:sequence> <xs:attributename="required"type="xs:boolean"> <xs:annotation> <xs:appinfo> <jaxb:propertygenerateIsSetMethod="false"/> </xs:appinfo> </xs:annotation> </xs:attribute> <xs:attributename="type"type="xs:string"/> <xs:attributename="context"type="xs:string"/> </xs:extension> </xs:complexContent> </xs:complexType> <xs:elementname="header"type="Header"/> <xs:complexTypename="Header"> <xs:complexContent> <xs:extensionbase="BaseResource"> <xs:sequence> <xs:elementname="value"type="xs:string"minOccurs="1"maxOccurs="1"/> </xs:sequence> <xs:attributename="required"type="xs:boolean"> <xs:annotation> <xs:appinfo> <jaxb:propertygenerateIsSetMethod="false"/> </xs:appinfo> </xs:annotation> </xs:attribute> </xs:extension> </xs:complexContent> </xs:complexType> <xs:elementname="headers"type="Headers"/> <xs:complexTypename="Headers"> <xs:sequence> <xs:elementref="header"maxOccurs="unbounded"> <xs:annotation> <xs:appinfo> <jaxb:propertyname="Headers"/> </xs:appinfo> </xs:annotation> </xs:element> </xs:sequence> </xs:complexType> <xs:elementname="parameters_set"type="ParametersSet"/> <xs:complexTypename="ParametersSet"> <xs:sequence> <xs:elementref="parameter"maxOccurs="unbounded"minOccurs="0"> <xs:annotation> <xs:appinfo> <jaxb:propertyname="Parameters"/> </xs:appinfo> </xs:annotation> </xs:element> </xs:sequence> </xs:complexType> <xs:elementname="schema"type="Schema"/> <xs:complexTypename="Schema"> <xs:complexContent> <xs:extensionbase="Link"> <xs:sequence> <xs:elementname="name"type="xs:string"minOccurs="0"maxOccurs="1"/> <xs:elementname="description"type="xs:string"minOccurs="0"maxOccurs="1"/> </xs:sequence> </xs:extension> </xs:complexContent> </xs:complexType> <xs:elementname="general_metadata"type="GeneralMetadata"/> <xs:complexTypename="GeneralMetadata"> <xs:complexContent> <xs:extensionbase="DetailedLink"> <xs:sequence> <xs:elementname="name"type="xs:string"minOccurs="0"maxOccurs="1"/> <xs:elementname="description"type="xs:string"minOccurs="0"maxOccurs="1"/> </xs:sequence> </xs:extension> </xs:complexContent> </xs:complexType> <xs:elementname="rsdl"type="RSDL"/> <xs:complexTypename="RSDL"> <xs:sequence> <xs:elementname="description"type="xs:string"minOccurs="0"/> <xs:elementtype="Version"name="version"minOccurs="0"maxOccurs="1"/> <xs:elementref="schema"minOccurs="0"maxOccurs="1"/> <xs:elementtype="GeneralMetadata"name="general"minOccurs="0"maxOccurs="1"/> <xs:elementtype="DetailedLinks"name="links"minOccurs="0"/> </xs:sequence> <xs:attributename="href"type="xs:string"/> <xs:attributename="rel"type="xs:string"/> </xs:complexType>
Examples
[edit ]List resources
[edit ]<linkrel="get"href="/api/clusters"> <request> <http_method>GET</http_method> <headers> <headerrequired="false"> <name>Filter</name> <value>true|false</value> </header> </headers> <url> <parameters_set> <parametercontext="query"type="xs:string"required="false"> <name>search</name> <value>searchquery</value> </parameter> <parametercontext="matrix"type="xs:boolean"required="false"> <name>case_sensitive</name> <value>true|false</value> </parameter> <parametercontext="matrix"type="xs:int"required="false"> <name>max</name> <value>maxresults</value> </parameter> </parameters_set> </url> <body/> </request> <response> <type>Clusters</type> </response> </link>
Get resource
[edit ]<linkrel="get"href="/api/clusters/{cluster:id}"> <request> <http_method>GET</http_method> <headers> <headerrequired="false"> <name>Filter</name> <value>true|false</value> </header> </headers> <body/> </request> <response> <type>Cluster</type> </response> </link>
Update resource
[edit ]<linkrel="update"href="/api/clusters/{cluster:id}"> <request> <http_method>PUT</http_method> <headers> <headerrequired="true"> <name>Content-Type</name> <value>application/xml|json</value> </header> <headerrequired="false"> <name>Correlation-Id</name> <value>anystring</value> </header> </headers> <body> <type>Cluster</type> <parameters_set> <parametertype="xs:string"required="false"> <name>cluster.name</name> </parameter> <parametertype="xs:string"required="false"> <name>cluster.description</name> </parameter> <parametertype="xs:string"required="false"> <name>cluster.cpu.id</name> </parameter> <parametertype="xs:int"required="false"> <name>cluster.version.major</name> </parameter> <parametertype="xs:int"required="false"> <name>cluster.version.minor</name> </parameter> <parametertype="xs:double"required="false"> <name>cluster.memory_policy.overcommit.percent</name> </parameter> <parametertype="xs:boolean"required="false"> <name>cluster.memory_policy.transparent_hugepages.enabled </name> </parameter> <parametertype="xs:string"required="false"> <name>cluster.scheduling_policy.policy</name> </parameter> <parametertype="xs:int"required="false"> <name>cluster.scheduling_policy.thresholds.low</name> </parameter> <parametertype="xs:int"required="false"> <name>cluster.scheduling_policy.thresholds.high</name> </parameter> <parametertype="xs:int"required="false"> <name>cluster.scheduling_policy.thresholds.duration</name> </parameter> <parametertype="xs:string"required="false"> <name>cluster.error_handling.on_error</name> </parameter> <parametertype="xs:boolean"required="false"> <name>cluster.virt_service</name> </parameter> <parametertype="xs:boolean"required="false"> <name>cluster.gluster_service</name> </parameter> <parametertype="xs:boolean"required="false"> <name>cluster.threads_as_cores</name> </parameter> <parametertype="xs:boolean"required="false"> <name>cluster.tunnel_migration</name> </parameter> </parameters_set> </body> </request> <response> <type>Cluster</type> </response> </link>
Create resource
[edit ]<linkrel="add"href="/api/clusters"> <request> <http_method>POST</http_method> <headers> <headerrequired="true"> <name>Content-Type</name> <value>application/xml|json</value> </header> <headerrequired="false"> <name>Expect</name> <value>201-created</value> </header> <headerrequired="false"> <name>Correlation-Id</name> <value>anystring</value> </header> </headers> <body> <type>Cluster</type> <parameters_set> <parametertype="xs:string"required="true"> <name>cluster.data_center.id|name</name> </parameter> <parametertype="xs:string"required="true"> <name>cluster.name</name> </parameter> <parametertype="xs:int"required="true"> <name>cluster.version.major</name> </parameter> <parametertype="xs:int"required="true"> <name>cluster.version.minor</name> </parameter> <parametertype="xs:string"required="true"> <name>cluster.cpu.id</name> </parameter> <parametertype="xs:string"required="false"> <name>cluster.description</name> </parameter> <parametertype="xs:double"required="false"> <name>cluster.memory_policy.overcommit.percent</name> </parameter> <parametertype="xs:boolean"required="false"> <name>cluster.memory_policy.transparent_hugepages.enabled</name> </parameter> <parametertype="xs:string"required="false"> <name>cluster.scheduling_policy.policy</name> </parameter> <parametertype="xs:int"required="false"> <name>cluster.scheduling_policy.thresholds.low</name> </parameter> <parametertype="xs:int"required="false"> <name>cluster.scheduling_policy.thresholds.high</name> </parameter> <parametertype="xs:int"required="false"> <name>cluster.scheduling_policy.thresholds.duration</name> </parameter> <parametertype="xs:string"required="false"> <name>cluster.error_handling.on_error</name> </parameter> <parametertype="xs:boolean"required="false"> <name>cluster.virt_service</name> </parameter> <parametertype="xs:boolean"required="false"> <name>cluster.gluster_service</name> </parameter> <parametertype="xs:boolean"required="false"> <name>cluster.threads_as_cores</name> </parameter> <parametertype="xs:boolean"required="false"> <name>cluster.tunnel_migration</name> </parameter> </parameters_set> </body> </request> <response> <type>Cluster</type> </response> </link>
Delete resource
[edit ]<linkrel="delete"href="/api/clusters/{cluster:id}"> <request> <http_method>DELETE</http_method> <headers> <headerrequired="false"> <name>Correlation-Id</name> <value>anystring</value> </header> </headers> <url> <parameters_set> <parametercontext="matrix"type="xs:boolean"required="false"> <name>async</name> <value>true|false</value> </parameter> </parameters_set> </url> <body/> </request> </link>
Code generation
[edit ]RSDL URI descriptor
[edit ]<linkrel="add"href="/api/clusters"> <request> <http_method>POST</http_method> <headers> <headerrequired="true"> <name>Content-Type</name> <value>application/xml|json</value> </header> <headerrequired="false"> <name>Expect</name> <value>201-created</value> </header> <headerrequired="false"> <name>Correlation-Id</name> <value>anystring</value> </header> </headers> <body> <type>Cluster</type> <parameters_set> <parametertype="xs:string"required="true"> <name>cluster.data_center.id|name</name> </parameter> <parametertype="xs:string"required="true"> <name>cluster.name</name> </parameter> <parametertype="xs:int"required="true"> <name>cluster.version.major</name> </parameter> <parametertype="xs:int"required="true"> <name>cluster.version.minor</name> </parameter> <parametertype="xs:string"required="true"> <name>cluster.cpu.id</name> </parameter> <parametertype="xs:string"required="false"> <name>cluster.description</name> </parameter> <parametertype="xs:double"required="false"> <name>cluster.memory_policy.overcommit.percent</name> </parameter> <parametertype="xs:boolean"required="false"> <name>cluster.memory_policy.transparent_hugepages.enabled</name> </parameter> <parametertype="xs:string"required="false"> <name>cluster.scheduling_policy.policy</name> </parameter> <parametertype="xs:int"required="false"> <name>cluster.scheduling_policy.thresholds.low</name> </parameter> <parametertype="xs:int"required="false"> <name>cluster.scheduling_policy.thresholds.high</name> </parameter> <parametertype="xs:int"required="false"> <name>cluster.scheduling_policy.thresholds.duration</name> </parameter> <parametertype="xs:string"required="false"> <name>cluster.error_handling.on_error</name> </parameter> <parametertype="xs:boolean"required="false"> <name>cluster.virt_service</name> </parameter> <parametertype="xs:boolean"required="false"> <name>cluster.gluster_service</name> </parameter> <parametertype="xs:boolean"required="false"> <name>cluster.threads_as_cores</name> </parameter> <parametertype="xs:boolean"required="false"> <name>cluster.tunnel_migration</name> </parameter> </parameters_set> </body> </request> <response> <type>Cluster</type> </response> </link>
Generated code signature(s)
[edit ]/** * Adds Cluster object. * @param cluster {@link org.ovirt.engine.sdk.entities.Cluster} * cluster.data_center.id|name * cluster.name * cluster.version.major * cluster.version.minor * cluster.cpu.id * [cluster.description] * [cluster.memory_policy.overcommit.percent] * [cluster.memory_policy.transparent_hugepages.enabled] * [cluster.scheduling_policy.policy] * [cluster.scheduling_policy.thresholds.low] * [cluster.scheduling_policy.thresholds.high] * [cluster.scheduling_policy.thresholds.duration] * [cluster.error_handling.on_error] * [cluster.virt_service] * [cluster.gluster_service] * [cluster.threads_as_cores] * [cluster.tunnel_migration] * @return * {@link Cluster } * @throws ClientProtocolException * Signals that HTTP/S protocol error has occurred. * @throws ServerException * Signals that an oVirt api error has occurred. * @throws IOException * Signals that an I/O exception of some sort has occurred. */ publicClusteradd(org.ovirt.engine.sdk.entities.Clustercluster)throws ClientProtocolException,ServerException,IOException{ .... } /** * Adds Cluster object. * @param cluster {@link org.ovirt.engine.sdk.entities.Cluster} * cluster.data_center.id|name * cluster.name * cluster.version.major * cluster.version.minor * cluster.cpu.id * [cluster.description] * [cluster.memory_policy.overcommit.percent] * [cluster.memory_policy.transparent_hugepages.enabled] * [cluster.scheduling_policy.policy] * [cluster.scheduling_policy.thresholds.low] * [cluster.scheduling_policy.thresholds.high] * [cluster.scheduling_policy.thresholds.duration] * [cluster.error_handling.on_error] * [cluster.virt_service] * [cluster.gluster_service] * [cluster.threads_as_cores] * [cluster.tunnel_migration] * @param expect * [201-created] * @param correlationId * [any string] * @return * {@link Cluster } * @throws ClientProtocolException * Signals that HTTP/S protocol error has occurred. * @throws ServerException * Signals that an oVirt api error has occurred. * @throws IOException * Signals that an I/O exception of some sort has occurred. */ publicClusteradd(org.ovirt.engine.sdk.entities.Clustercluster,Stringexpect,StringcorrelationId)throws ClientProtocolException,ServerException,IOException{ .... }
References
[edit ]- ^ "RESTful Service Description Language (RSDL)". balisage.net.