Skip to content

Does WoT.Request need a "type" attribute #70

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
danielpeintner opened this issue Oct 19, 2017 · 14 comments
Closed

Does WoT.Request need a "type" attribute #70

danielpeintner opened this issue Oct 19, 2017 · 14 comments

Comments

@danielpeintner
Copy link
Contributor

The WoT.Request besides other information provides an attribute type which is defined as

enum RequestType {
    "property",
    "action",
    "event",
    "td"
};

I wonder why we actually need this information. A request of type

Hence no need to have this additional information. Moreover, It even complicates the situation because we need to define what happens if onInvokeAction() receives a request of type "property" ... (failure?)

@danielpeintner
Copy link
Contributor Author

I noticed onObserve() is a somewhat special request. I would tend to say we create a dedicated ObserverRequest without complicating the normal requests for property and actions? Not sure...

Maybe we also state which Request fields are optional in the WebIDL.
request.name seems to be the only attribute that is required.

@zolkis
Copy link
Contributor

zolkis commented Oct 19, 2017

Since we haven't defined algorithms yet, perhaps it is hard to infer from WebIDL alone how things are supposed to work. So apologies for a long reply, and sorry if I will state obvious things.

The wot.expose() function only creates an ExposedThing based on a TD defined either as a URL or a JSON description. The app can attach request handlers, register, start/stop. The request handlers can use the emitEvent() method (it is unclear whether should we have this method explicitly defined here, or just use a platform provided event emitter function).
The ExposedThing.register() function will publish the generated/overloaded TD.
The ExposedThing.start() function will start serving requests.

When TD's include protocol binding descriptions, these will be used by implementations for generating default request handlers. Then ExposedThings can be just created based on a TD and then just call register(), start(), stop() etc. Of course an app script can overload the TD definitions/bindings.

When an app script defines or overloads an ExposedThing, it needs to define request handler functions. They cannot be modeled with event handlers since there must be exactly one handler for a request type in a server object (as opposed, an event can have multiple handlers: all clients that are subscribed to it). So this is modeled with functions exposed on ExposedThing.

The possible requests are defined by the TD, and will certainly fall in the following categories:

  1. Implementation defined request handlers: add/remove property/action/event. At the moment these functions have local effect (in writing a TD for the ExposedThing before ExposedThing.register() is called), and not serving external requests for adding/removing properties/actions/events, but may be used from application defined request handlers.
  2. Application defined request handlers, as in the enum: property retrieve/update, action invocation, subscribing to a default event defined by implementation (e.g. TD changes, such as property addition/removal etc), and events defined and emitted by the ExposedThing. They provide implementation of the request handling, e.g. protocol bindings, event handling, etc.

Now on why do we have the current API design with Request and the 4 types of request handlers: after playing with various designs, this seemed to be the simplest:

  • requests all share source, target, and may have options
  • requests should be responded to with ok, data, or error.
    Hence the Request interface.

You are right that type property is not really needed on Request, since only the implementation can create Request objects and then will know to dispatch them to the right request handlers (property, action or event).

However, I exposed it for the sake of clarity (and symmetry with ConsumedThing definitions) until we have the algorithm descriptions in place.

You would be also right (and there is a Note about it) that on ConsumedThing the observe() method could replace addEventListener() etc.

I expect we clarify these when we discuss event modeling on the F2F. My choice would be using observe(), and that matches to Requests, default events (TD change related) and application events.

In summary, indeed we need to consolidate the API in this regard.

@mkovatsc
Copy link
Contributor

mkovatsc commented Oct 24, 2017

I fear that this is currently headed toward a solution that exposes all the nitty gritty details to the script, so that we do not gain anything from the Thing abstraction; we basically script some kind of mutated REST framework. Also the parts such as configurable = false;, enumerable = true;, and differentiating between register() and start() appear to be overengineering a simple target. The Scripting API must not mutate to a something that tries to standardize the complete stack implementation!

The original idea was to focus on the pure application logic following a reactive programming paradigm: The script tells the runtime it should manage a Property of a certain type and the script gets notified when it's being changed or read, although in many cases the script does not care about reading and the runtime can answer directly without context-switch. If someone wants to have access to every last system and implementation detail, they can work on the inside of a Servient implementation.

It would be great if we can continue with a minimalist, logic-focused API and collect the implementation aspects and internal APIs outside the API specification? After a full iteration, we can check which aspects should be exposed to the script and start a new iteration.

@zolkis
Copy link
Contributor

zolkis commented Oct 25, 2017

Thank you for the comments.

Also the parts such as configurable = false;, enumerable = true;

It is standard property management.

differentiating between register() and start()

They do different things. register() will publish the TD, start() will start serving requests. In a servient implementation these are legitimate steps if the app wants to control when to serve requests.

we basically script some kind of mutated REST framework

There is no way out of specifying request handlers on an ExposedThing. If you have API suggestions for that, please make them.

@zolkis
Copy link
Contributor

zolkis commented Oct 25, 2017

To me it seems that removing type from Request should be possible, because the implementation can dispatch the right Request object to the right handler.

However, since it is the implementation that can create Request objects, type will never be out of sync with the handler. So it is just an extra information the apps has in Request objects, and may be useful.

Even if remove the type property from Request, we still do need the RequestType enum for the onObserve() method.

We can also pursue an alternative API design for ExposedThing handlers, please make suggestions (whole WebIDL for ExposedThing functionality).

@mkovatsc
Copy link
Contributor

configurable = false;, enumerable = true;

It is standard property management.

What is the benefit of having this? It is not protecting anything, since the script that might want call remove is the same that can simple change a false to true. For enumerable, I don't understand the purpose? Making it hidden in the TD?

I am going over more details by writing the Current Practices for the Burlingame Current Practices. In that course, I will aim to make for API proposals.

@zolkis
Copy link
Contributor

zolkis commented Oct 25, 2017

First of all, property descriptors have been there in the API. I wonder why it is now that this is suddenly challenged.

With enumerable a script can define e.g. private properties to an ExposedThing that are not enumerated when the object properties are listed on the object, but still kept in object context.

configurable is true when the type can be changed and if the property may be deleted. This is not important now but may be if an ExposedThing allows external change request to its TD.

I guess writeable is clear.

I surmise there might be a difference in how TD vs scripts are understood.
In my view, a script can do 2 things in a servient:

  • define an ExposedThing, generate its TD based on the script, register/start/stop it
  • create local ConsumedThing objects based on TDs, which can be used in the app specific implementation of the ExposedThing.

Welcome to propose APIs, only one point: let's try to avoid mixing TD fragments and code in designing a solution. if we have to keep TD fragments around, it proves we cannot do a proper scripting API - or that we don't need it.

@mkovatsc
Copy link
Contributor

You are mixing the concepts of JavaScript objects with the concepts of WoT Interactions. The writable given in ThingPropertyInit has been corresponding to the TD term writable. There is a duality that might be helpful, but so far it is an individual assumption.

@zolkis
Copy link
Contributor

zolkis commented Oct 25, 2017

The TD spec is obviously missing out on property management.

@mkovatsc
Copy link
Contributor

Let's come back to the original issue. I opened new issues for the new topics started here.

Does WoT.Request need a "type" attribute?

WoT.Request turned out to be part of a low-level CRUDN API. For this, I would say it would need the type attribute. Yet then ExposedThing would also only need a single onRequest() call instead of onRetrieveProperty(), onInvokeAction(), etc. (and split type 'event' into 'observe' and 'subscribe').

Furthermore, the WoT Scripting API should remain a simple API on top of the Thing abstraction. Let's not overengineer it to a generic CRUDN IoT framework and keep it simple and the Scripting API slim with only what the application logic needs. Logging, accounting, analytics, etc. are left the Servient implementation. Please feel encouraged to document your requirements, possibly in a, for instance, WoT Servient API document for later exploitation.

@zolkis
Copy link
Contributor

zolkis commented Oct 26, 2017

then ExposedThing would also only need a single onRequest() call

Yes, that would be logical.

the WoT Scripting API should remain a simple API on top of the Thing abstraction

Actually with Request we simplified the API a lot, and also got it closer to IoT paradigms external to WoT. In my book that's a gain.

If we want to revert to a more verbose API and client code, we can discuss that in the next call.

@mkovatsc
Copy link
Contributor

mkovatsc commented Oct 26, 2017

What verbose client code? This is about WoT Servers / ExposedThings.

When the script has to do its own Request analysis and multiplexing, the code becomes more verbose.

Your assumption sounds a bit like "we simplified the API a lot for people already programming IoTivity" (or any other generic framework on the request/reponse level for that matter) and it falls under the critique by Mozilla and others: why standardize this at all? There is no point in standardizing a generic IoT framework.

@zolkis
Copy link
Contributor

zolkis commented Oct 26, 2017

Yet in fact that's what we are doing in WoT. Just by implementing "generic" in our "TD" way.

@zolkis
Copy link
Contributor

zolkis commented Feb 14, 2018

Obsoleted by #86.

@zolkis zolkis closed this as completed Feb 14, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants