Tango Feature Request 4: Defining a standard Tango REST API
|
|
---|---|
Hi tangoers, During the 29th Tango Meeting we announced the possibility to make a standard Tango REST API. This feature request has been written in a more formal way below as a tentative for helping the discussion. Please give any feedback about the definition of this TFR and I will update this page as soon as I can. I will open a new topic in the forum to discuss especially about the API . Cheers, Vincent Code name Scope The scope of this feature request is focus on the definition of a REST API for Tango. This will include the definition of the HTTP request (URL, content, …) Context Several web application have been develop for Tango and a REST api has been often used. Here is a list of different existing implementations:
Please find more about Jive on Android project from Solaris: Android app: https://github.com/lukaszmitka/jive_for_android https://github.com/lukaszmitka/restful_jive_for_android REST interface: https://github.com/lukaszmitka/restful_tango_interface_2 (TODO) The purpose is to access the Tango world through the Gotan REST server A document describing the api: https://www.dropbox.com/s/9nqeabizxlmj6zp/Gotan%20-%20Tango%20REST.pdf?dl=0 Problem to solve There are many way to define an API using the architecture REST. Also there are different constraints among them the Stateless is the most important. RESTful is defining a set of rule to guarantee a compatibility between all of the Restful software. How to handle command with RESTful compatibility can be one of the topics among others. Also Tango already defines a standard API on how to access devices, attributes, properties… That can be matched with a Tango Rest Api. All the web client application won't be compatible if all the different Tango REST server have a different interface. Goal and milestones: The goal is to collect the different experiences to define a stable first version of the standard. First of all a proposition with different option will be released then to collect the feedback from the overall community. This will define a alpha version of the TANGO REST API Finally a document will release before the Tango meeting the 30rd for approval from the board. This will define a beta version of the TANGO REST API. Output: The first version of this API is expected to be release with:
Benefit: A standard API provide an interoperability between the different implementation of the web server and the client. The leverage of the standard will allow to create an active ecosystem. The expectation is to grow the web development of Tango in a coherent way for the users. Possible later improvement: Performance test: Can be part of the compliance test Edit: - added links for the Solaris project (Lukasz) - added implementation guidelines (Igor)
Vincent Hardion
Control System MAX IV Laboratory |
|
|
---|---|
Hi Tangoers, Please find more about Jive on Android project from Solaris: Android app: REST interface: All feedback is most welcome
Kind Regards,
Lukasz Zytniak Control Software Engineer ————————————————————— |
|
|
---|---|
Hi All, Here I shortly highlight the ideas implemented in mTangoREST API. For more details please refer to the page. 1. Attributes GET {API_ROOT}/device/sys/tg_test/1/double_scalar – access to the 'double_scalar' attr of the TangoTest device. This is simple GET request. The response looks like the following: PUT request writes an attribute: PUT {API_ROOT}/device/sys/tg_test/1/double_scalar_w=2%2E78 NOTE: that a client is responsible for encoding special characters, i.e. %2E => '.' in this particular case. Neither DELETE nor POST are not allowed. 1.1 Image attributes: As our applications are browser oriented images are encoded into JPEG and BASE64 and injected into response:
On the server side byte array received from a remote Tango device is wrapped with BufferedImage without copying the array and is immediately written into the response. This approach does not support TIFF images. So the server side must ensure to convert all images into JPEG first. 2. Commands Command execution is always a GET request, even with an argument: GET {API_ROOT}/device/sys/tg_test/1/DevString=Hello%20World%20!!! And this was a major question when I first started to design the API. GET was chosen just for simplicity – one can execute commands directly from the browser's address bar. Only GET is supported. 3. Events GET {API_ROOT}/device/sys/tg_test/1/long_scalar_w.change Events implementation is based on the Comet specification, i.e. server blocks request till it gets a notification from the remote Tango device. This approach may utilize all available connections in heavily events oriented applications. Therefore client and server must implement multiplexing/demultiplexing of events' requests. Plus it might be useful to have a timeout so that if server does not get a notification within the specified period of time - it releases the request and responses with an old value. In this case client may resend the request. Other supported event types are: periodic, user, archive. Only GET is supported. 4. Family/domain/device browsing As Tango hierarchy perfectly matches REST's idea of a resource tree this case is straight forward: GET {API_ROOT}/devices lists all the devices defined in the Tango DB attached to this mTango host:
GET {API_ROOT}/device/ lists all available domains in the Tango DB:
GET {API_ROOT}/device/{domain} lists all families in the Tango DB GET {API_ROOT}/device/{domain}/{family} lists all members of the family in the Tango DB. GET {API_ROOT}/device/{domain}/{family}/{member} displays status of the device:
Only GET is supported. 4. Attributes', commands' infos GET {API_ROOT}/device/{domain}/{family}/{member}/attributes lists all attributes of the device. GET {API_ROOT}/device/{domain}/{family}/{member}/{attribute}/info displays info of the attribute. Same for the commands: GET {API_ROOT}/device/{domain}/{family}/{member}/commands GET {API_ROOT}/device/{domain}/{family}/{member}/{command}/info 4. Caching Caching in terms of HTTP response header is not supported. But mTangoREST server performs a binary caching of the response for 200 ms. This was a quick overview of the REST API implemented in mTangoREST API. For more details please refer to the page. Apart from API specification I think it is important to release some implementation guidelines, i.e. caching and optimizations advises. For instance, implementation must be clever enough to combine several requests, i.e. several clients read the same attribute. This is implemented in mTangoREST server. And do we really need so much time? In other words currently we will only get a beta version in an year. I believe this task can be accomplished much faster: in three month release alpha version, then perform a beta before next Tango meeting so board can agree on Release Candidate 1. Cheers, Igor. |
|
|
---|---|
Ingvord Thanks for your feedback. Great idea for the implementation guidelines. I will add that to the first post. Effectively we can have a stable version before the next Tango meeting. An approval from the community can be done online and just have a official presentation to the board. /Vincent
Vincent Hardion
Control System MAX IV Laboratory |
|
|
---|---|
Hi, Today I have looked through the Solaris REST project. Here is a small overview of it: Request: This gives a full device list stored in the db:
Attribute write/read: Attribute write request:
Response:
Read attribute request:
Response:
API also provides other interesting features: <device-prefix>/ping_device. NOTE from now on <device-prefix> = tango/rest/{host}:{port}/Device/{domain}/{family}/{name} <device-prefix>/get_device_info Attributes: <device-prefix>/get_attribute_list;<device-prefix>/plot_attribute/{attr_name} [Reads attribute and returns its values as array or set of arrays depending if attribute is of type SPECTRUM or IMAGE.]; PUT <device-prefix>/read_attributes Tango proxy related: <device-prefix>/set_source;<device-prefix>/get_source;<device-prefix>/set_timeout_milis /{value} Commands: <device-prefix>/command_list_query;PUT <device-prefix>/command_inout/{command_name}/{argin};<device-prefix>/black_box/{number_of_commands};PUT <device-prefix>/extract_plot_data/{command_name} Dealing with properties: <device-prefix>/get_property_list;<device-prefix>/get_property/{prop_name};PUT <device-prefix>/put_property/{prop_name}/{prop_val} Interesting ideas of this API: Provided access to properties (not implemented in mTangoREST) Provided access to proxy control like source, timeout (not implemented in mTangoREST) Arguments passed as a part of URL, i.e. <device-prefix>/write_attribute/{attr_name}/{argin} (in mTangoREST arguments are passed via '=', i.e. PUT <device-prefix>/{attr_or_command_name}={argin}) My thoughts on this API: First of all this is not a REST API meaning that it does not follow REST specification. For instance, a tree structure of the resources ain't satisfied, i.e. instead of <device-prefix>/attributes we have <device-prefix>/get_attribute_list. API overflowed with redundant case specific commands, like 'plot_attribute', 'put_property', 'command_inout' and so on. Return value: "measure date: 14\/06\/2015 15:00:30 + 137ms\nquality: VALID\nRead:\t3.14\n” seems very strange to me saying the least. This is a string client must parse! Other issue is the date – it should be simple timestamp, because it is much more convenient for the client then to do something with it. Errors handling: API does not return anything more than “Attribute double_xxx not read. Unable to connect with device sys\/tg_test\/1” [NOTE: there is no such attribute 'double_xxx'], i.e. in case of any error raised by a tango proxy on the serer side a client will get “Unable to connect” Tango related features: API exports any Tango data base to the outside world. This is very questionable approach, hence very interesting if not 'Device' anchor in between, i.e. GET http://localhost:8080/tango/rest/localhost:10000/sys/tg_test/1 seems much more elegant in this case. Another issue with this anchor is that it is capitalized, i.e. server won't match anything if one asks for …/localhost:10000/device/sys/… Tango hierarchy is not supported: GET restfultango/rest/localhost:10000/device/sys/tg_test returns 404 Commands execution always requires argin, even if it is a command(void). Moreover in case of void it requires special argin=DevVoidArgument No events. No TangoAccessControl integration. Conclusions API definitely provides some interesting ideas could be brought into Tango REST API specification. Like access to properties and control of the Tango proxy. P.S. next week I will look through GOTAN REST API. Meanwhile I will appreciate if other involved people look through mTangoREST, GOTAN and Solaris's RESTful Tango so we can start to discuss common things and how to combine them into a single Tango REST API |
|
|
---|---|
I would like to rise here several questions for further discussion: 1) should API export Tango database? Or API must be limited with only one DB? 2) Mapping Tango hierarchy to REST API. Strictly following REST specification we will end up with something like this:
Which is quite weired. To avoid this weariness I suggest to replace 'resources' anchor with actual resource:
So that each resource implements has many relationship, i.e. Returns all families of the sys-domain. 3) Should command be a GET or PUT request? 4) Passing arguments: there are three possibilities I see so far: in request's body; as a part of URL; or as a parameter of URL (double_scalar?argin=3.14). So which one should we choose? |
|
|
---|---|
Unfortunately I was not able to full-scale test the GoTan project. As the only request it servers is
This one returns an array of devices defined in the Tango DB:
Any other GET request to the server returns 405 (Method is not allowed). And POST an attribute, e.g. POST http://localhost:8080/gotan/sys/tg_test/1/double_scalar crashes the server:
But OK, since it is only a proof of the concept and API is very well described in this document (https://www.dropbox.com/s/9nqeabizxlmj6zp/Gotan%20-%20Tango%20REST.pdf?dl=0) Its implementation can be omitted. The only thing from my point of view worth to stress is that API is a little bit messy in terms of using http methods. For instance, attribute write must be PUT not POST, as it does not create anything new, just writes a new value, i.e. updates an attribute. Read attribute must be GET and so on. Anyway next week I will prepare a draft document that defines REST API for Tango. |
|
|
---|---|
REST API specification proposal ver. 0.1 Any input is welcome! |
|
|
---|---|
Hi, It has been useful for me to look at this since I am involved in a project where we are going to use a rest api as well. It looks a well though api, I just have a few comments/questions: It migth be easier to filter in this way.
I hope it these comments help you somehow, cheers. Mikel |
|
|
---|---|
Hi Mikel, Thanks for your input! mikegu I agree - PUT seems a little bit more natural, as it updates the "state" of the device, i.e. executes a command. mikegu There will be a generic filter implementation for any response, i.e. one can always request only that portion of the response which is actually needed. In terms of implementation this will be a servlet filter on the server side (at least I think to implement it in this way). mikegu Tango Database is just another Tango device. You can access it using the same API. mikegu I agree that this approach is quite misleading and counterintuitive. I can not image any scenario where it can be useful. In fact in the next edition of the proposal I will remove PATCH request at all. Apart from introducing unnecessary complexity there is also a problem - it might not be implemented everywhere. Like in raw Java HTTP library. |