Page History
...
Div | ||
---|---|---|
| ||
DO NOT EDIT THE CONTENT OF THIS PAGE DIRECTLY (EXCEPT INSIDE THE DIV BELOW WITH ID=DESCRIPTION), UNLESS YOU KNOW WHAT YOU'RE DOING. |
Div | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Using the The RESTful Web Service plugin allows exposing business logic can be exposed as a RESTful Web Service.
About RESTful Web ServicesRESTful Web Services utilize the features of the HTTP Protocol to provide the API of the Web Service. For example, it uses the HTTP Request Types to indicate the type of operation:
Using these 4 HTTP Request Types a RESTful API mimics the CRUD operations (Create, Read, Update & Delete) common in transactional systems. A defining feature of REST is that it is stateless: each call the to a RESTful Web Service is completely stand-alone: it has no knowledge of previous requests. Implementing a RESTful Web Service in ServoyThe A RESTful Web Service plugin does not contain any client side functions or properties, it is a 100% server side operating plugin.A RESTful Web Service can be created by creating endpoint is created by defining a Form in a solution Solution and implement implementing one or more of the following methods to the Form:
| Used for the retrieval of dataGET
| Used for the creation of new recordsUsed for the removal of dataPOST
DELETE
PUT Used for updating data ws_authenticate N/A Used to authenticate the requesting client ws_response_headers N/A Used for setting HTTP headers in the outgoing response By performing an HTTP GET on the url
The RESTful Web Service endpoint is then available through the URL
By performing an HTTP DELETE on the url {serverUrl}/servoy-service/rest_ws/{solutionName}/{formName}, the ws_delete() method will be invoked. The method has to return a Boolean value: – true: to indicate successful deletion. This result will generate an OK response (HTTP 200) – false: to indicate delete failure. This response will generate a NOT_FOUND response (HTTP 404) Implement ws_update(content):Boolean to allow updating existing data By performing an HTTP PUT on the url {serverUrl}/servoy-service/rest_ws/{solutionName}/{formName}, the ws_update() method will be invoked. Data has to be supplied in the body of the HTTP request. The method has to return a Boolean value: – true: to indicate successful update. This result will generate an OK response (HTTP 200) – false: to indicate update failure. This response will generate a NOT_FOUND response (HTTP 404) Implement ws_authenticate(user, password):Object to allow authentification If present, it will be called before performing any rest operation (ws_read, ws_create, ws_delete, ws_update). If the method returns false or null an UNAUTHORIZED response is generated (HTTP 401). Any other return value will be added as a request parameter with name "ws_authenticate" to the incoming request. Implement ws_response_headers():Object to allow setting response headers The method can return either a string or an array of strings of type "headerKey=headerValue". These will be set in the response header. In case the matching method for the specific HTTP operation (GET, POST, DELETE or PUT) does not exists on the form, an INTERNAL_SERVER_ERROR response (HTTP 500) will be generated. Request parametersAdditional parameters can be specified in the URL of the HTTP Requests. There are two variations and how they are forwarded to the ws_* methods differs. Additional URL path elements
The additional URL path elements {someValue} and {anotherValue} will be passed into the ws_* method as additional arguments. This means that for ws_read() and ws_delete() they will be the first and second argument and for ws_create() and ws_update() they will be the 2nd and 3rd argument, as these method already have by default the content of the request as first argument. Query parameters If the URL contains Query parameters, these will be passed into the ws_* method as an additional last argument. This last argument is a JavaScript object containing all keys as properties with the values associated with the key in a Array: Object<Array<String>> Example
A HTTP Get Request on url {serverUrl}/servoy-service/rest_ws/myRestAPISolution/APIv1/foo/bar?name=John&age=30&pet=Cat&pet=Dog would result in invoking the ws_read method on form 'APIv1' of solution 'myRestAPISolution'. The ws_read function will be invoked with three parameters: 'foo', 'bar', {name: 'John' , age: 30 , pet: 'Cat', 'Dog' }
StatelessRESTful Web Services are to be stateless. As subsequent requests to the RESTful Web Service API might be handled by different headless clients in the pool of clients configured for the plugin, do not use any state in between calls to the API. This means at least the following:
HTTP RequestFor the POST and PUT operation (resp. ws_create() and ws_update() methods), data has to be supplied in the body of the HTTP Request. If the content in the body of the HTTP Request is missing, a NO_CONTENT response will be generates (HTTP 204). The supported Content-Types are JSON (application/json), XML (application/xml) and byte array (application/binary). The Content-Type can be explicitly set in the header of the HTTP Request:
Note: the charset is optional. If not specified, utf-8 will be assumed. If no valid Content-Type is set, the plugin will try to establish the type of the content based on the first character of the content:
When the Content-Type cannot be determined, an UNSUPPORTED_MEDIA_TYPE response will be generated (HTTP 415). The supplied value in the body of the HTTP request will be applied as argument to the invocation of the method. If the body Content-Type is not application/binary, it will be converted to a JavaScript object automatically. If the body content cannot be converted to a JavaScript object based on the Content-Type an INTERNAL_SERVER_ERROR response (HTTP 500) will be generated. HTTP ResponseBy default, the plugin will respond with the same Content Type as was specified in the HTTP Request. This can be overruled by specifying a different response Content-Type in the Accept header of the HTTP Request:
By default, the response will be encoded with the UTF-8 charset, if the response Content-Type is not application/binary with byte array as response. If the HTTP Request specified a different encoding, that will be used instead. If the encoding of the response needs to be different than the request encoding, this can be specified in the HTTP Request by setting the charset value in the Accept header:
Returning custom status codesWhile some of the HTTP Response status codes are hardcoded in the RESTful Webservices plugin (see this documentation), it is possible to control the HTTP Status codes from within the ws_* methods. Returning a custom HTTP Status Code can be done by throwing the specific value (a number) for the HTTP Status Code. For example, when a ws_update call comes in for a non-existing resource, the HTTP Status Code to return would be a "Not Found" status code, which is a 404. Returning the 404/Not Found HTTP Status code from within a ws_* method could be done the following way:
For convenience purposes, all available HTTP Status Codes are also listed under the HTTP Plugin shipped with Servoy, so instead of throwing the number 404 in the previous example, a more readable way would be to throw plugins.http.HTTP_STATUS.SC_NOT_FOUND See List_of_HTTP_status_codes on Wikipedia for additional information on all status codes It is also possible to append a detailed description for the returned status code
Authentication/Authorization The RESTful Web service plugin can be configured to check authentication/authorisation. When access is denied, an UNAUTHORIZED response is generated (HTTP 401). JSONP supportThe plugin supports so-called JSONP: a variation of JSON that allows cross domain data retrieval. The JSONP variation can be invoked by added a "callback" parameter to the HTTP Request URL:
When invoked with the value "myCallback" for the "callback" parameter, the returned JSON value will be wrapped in a function call to the "myCallback" function:
Pool of ClientsTo service the requests to the RESTful Web service API, the plugin creates a pool of (headless) clients. The maximum number of clients allowed can be set using . Multiple endpoints can be created by implementing the relevant With 2019.09 the {formName} can also be a scope so you don't need to create a form (thats more a ui element) If the method for one of the HTTP Request Types is not implemented, that operation is not available on the endpoint and when attempted to be called a METHOD_NOT_ALLOWED (HTTP 405) error will be thrown. The RESTful Web Service plugin does not have any client side functions or properties: all its magic happens by implementing the methods with the predefined
Keeping It StatelessRESTful Web Services are to be stateless. The RESTful Web Service plugin internally uses a pool of Headless Clients to handle multiple concurrent requests to the REStful Web Service API. As subsequent requests to the RESTful Web Service API might be handled by different headless clients in the pool of clients configured for the plugin, no state should be preserved in the headless client at the end of the call to the API. Therefore, make sure any state is cleared at the end of logic. This means at least the following:
Supporting GET RequestsGET Requests are supported on the endpoint if the If the return value is a JavaScript object, it will be serialized and then placed in the body of the HTTP Response. See Returning Binary Data for more info on returning binary content. If the return value of the method is null, a NOT_FOUND response (HTTP 404) will be generated. See what arguments you can receive in this method call. Supporting POST RequestsPOST Requests are supported on the endpoint if the The body content of the HTTP Request is passed into the If the body content cannot be converted to a JavaScript object / string based on the Content-Type, an INTERNAL_SERVER_ERROR response (HTTP 500) will be generated. If the content in the body of the HTTP Request is missing, a NO_CONTENT response will be generated (HTTP 204). The
The method can optionally return a JavaScript primitive/array/object or a byte array, from 2020.12 on you can return a JSFile object so you can stream large files to the client. If the return value is a JavaScript object, it will be serialized and then placed in the body of the HTTP Response. See Returning Binary Data for more info on returning binary content. See what other arguments you can receive in this method call. Supporting DELETE RequestsDELETE Requests are supported on the endpoint if the
See what arguments you can receive in this method call. Supporting PUT RequestsPUT Requests are supported on the endpoint if the
The body content of the HTTP Request is passed into the If the body content cannot be converted to a JavaScript object / string based on the Content-Type an INTERNAL_SERVER_ERROR response (HTTP 500) will be generated. If the content in the body of the HTTP Request is missing, a NO_CONTENT response will be generated (HTTP 204). See what other arguments you can receive in this method call.
Additional arguments - when adding Extra Data to the Request URL or return values in ws_authenticateAdditional data can be added in the URL of the HTTP Requests. There are two variations and how they are made available in the Additional URL Fragments Additional URL fragments can be added to the URL like:
The additional URL fragments Query Parameters If the URL contains Query parameters, these will be passed into the Note that if custom endpoint restrictions are implemented and the Combining Additional URL Fragments and Query Parameters
Example A HTTP Get Request on URL The
Supported Content Types & EncodingThe plugin supports the following Content Types:
Request Content-Type and Encoding The Content-Type of the HTTP Request can be explicitly set by the caller using the
For requests that specify body content (POST and PUT Requests (resp.
When the Content-Type cannot be determined, an UNSUPPORTED_MEDIA_TYPE response will be generated (HTTP 415). Response Content-Type and Encoding By default, the plugin will respond with the same content type as used in the HTTP Request. The client calling the RESTful Web Service can request a different response content type by specifying the desired content type for the Response by setting the The response will be encoded with the If the encoding of the response needs to be different than the request encoding, this can be specified in the HTTP Request by setting the charset value in the Accept header:
Returning Binary DataThe RESTful Web Services plugin supports returning binary data in GET operations. Binary data could for example be the content of a dataprovider of type MEDIA or the contents of a file read from disk. In this case, the body of the response will contain the actual stream of bytes. Clients consuming the web service must be able to handle the binary response. When the consuming client specifies the From 2020.12 on if you return large binary data, please use a JSFile wrapper around an actual file on disk, then the bytes are just streamed directly from disk to the client over the http request without the need to read the bytes fully in memory. Setting Custom HeadersCustom headers can be set in the response by implementing the
Each key/value pair will be added as Header to the HTTP Response. Returning Custom Status CodesWhile some of the HTTP Response status codes are hardcoded in the RESTful Webservices plugin, it is possible to control the HTTP Status codes from within the For example, when a
It is also possible to set the body content of the HTTP Response with a more elaborate message to give more context to the returned status code:
For convenience purposes, all available HTTP Status Codes are also listed under the HTTP Plugin, so instead of throwing the number 404 in the first example, a more readable way would be to throw plugins.http.HTTP_STATUS.SC_NOT_FOUND For additional explanation of all the status codes, see List_of_HTTP_status_codes on Wikipedia. Authentication/AuthorizationBy default access to any endpoint in unrestricted. The plugin supports 2 modes of implementing Authentication and authorization.
Global Restrictions Based on Servoy SecurityBy setting the plugins server property The endpoints must be called with HTTP Basic authentication to provide a username and password. The username/password supplied in the HTTP Request is validated against the users registered in Servoy's built-in security system and additionally against group membership. Access is denied if the user does not exist or the supplied password is incorrect, or the user doesn't belong to one of the specified groups. When access is denied, an UNAUTHORIZED response is generated (HTTP 401). Custom Endpoint RestrictionsFor each endpoint custom authentication and authorization can be added by implementing the If the method returns false or null an UNAUTHORIZED response is generated (HTTP 401). Any other return value will be added as an extra query parameter with the key JSONP supportThe plugin supports so-called JSONP: a variation of JSON that allows cross domain data retrieval. The JSONP variation can be invoked by added a 'callback' parameter to the HTTP Request URL:
When invoked with the value "myCallback" for the 'callback' parameter, the returned JSON value will be wrapped in a function call to the
Versioning support{serverUrl}/servoy-service/rest_ws/v2/mysolution/myform_or_scope/ or {serverUrl}/servoy-service/rest_ws/mysolution/v2/myform_or_scope/ This is supported (the 'v' has to be there and the '2' must be a number). What is looked up is in the 'myform_v2' form or the 'scope_v2' scope (for version 2 of the api). (supported since 2019.09) Nested call support{serverUrl}/servoy-service/rest_ws/mysolution/myscope/mymethod/mymethod2/arg1 The plugin will now lookup in 'mysolution' on the 'myscope' scope a method named 'ws_read_mymethod_mymethod2'; if that one is found it will call it with 'arg1' as an argument. If 'ws_read_mymethod_mymethod2' method is not found it will try: 'ws_read_mymethod' (that will then get 2 arguments: 'mymethod2' and 'arg1') and if that one is not found either it will fallback to 'ws_read' (with 3 arguments). Read more about method arguments. Pool of ClientsTo service the requests to the RESTful Web service API, the plugin creates a pool of (headless) clients. The maximum number of clients allowed can be set using the When there are more concurrent requests than the number of clients in the pool, by default the requests will wait until a client becomes available in the pool. This behavior can be altered by setting the "
SamplesA sample solution is included in the Servoy distribution (servoy_sample_rest_ws.servoy), detailing how to retrieve data from the http request and to return a response. For more information on RESTful Web Services, see: http://en.wikipedia.org/wiki/Representational_State_Transfer | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
HTML Table | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
id | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
class | servoy sSummary |
Table Row (tr) |
Table Cell (td) | Client pluginCode running inside a rest-ws request can access the request and the response using the rest_ws client plugin. For example, retrieve a custom header sent by the client:
Note that the client-plugin can only be used within a request handler, the function See API documentation for the plugin. Sample SolutionA sample solution is included in the Servoy distribution (servoy_sample_rest_ws.servoy), detailing how to retrieve data from the HTTP Request and to return a response. More information on RESTful Web ServicesSee the following links for more information on RESTful Web Services:
API Docs |
HTML Table | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|