You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
I propose that in order to discover services, we should leverage elements in the shell.
Optionally, add the type as a hint for the client to know what to expect:
Address can pick these links up and provice a convenient JS API, something like thus:
address.link('logical service name').get().then(function(response){// Do stuff with response here})
(This would need fleshing out; how would you address links by rel, for instance?)
Why title and not id? For a couple of reasons:
id is global to the page, and also used in determining document fragments; we should try and not interfere with this
title is more idiomatic; class is also used, however this is typically to determine the kind of service it is and not so much which specific service it is
title is semantically accurate, it is the logical name of the service
Options
Services could respond properly to OPTIONS requests such that clients may know what their options are with this service. We could leverage this in address to prepare requests. For instance, consider the following service:
If address sends an OPTIONS request to this service, it could return a response similar to the following:
200 OKAllow: HEAD,GET,PUT,DELETE,OPTIONS
Furthermore, the service could generate a body and send that to us as well, and so long as address can understand the body (and we can make it) we can prepare convenient APIs client side for interacting with these services. Here's an example of such a response from the fictional user preferences service:
From this, address can deduce that there are three meaningful APIs available for further exposure in JS: GET, POST, DELETE. The GET is simple (declared by the Allow,) header it's just a GET of https://luser.example.com, and can be exposed in the client as such:
Additionally, using the hypermedia constructs we've experimented with in the developer site, one may do something like this:
exportlink=[{rel: 'service embed',id: 'user preferences',accept: 'application/json'}]export(req,res,context)=>{// Data from the `user preferences` service is embedded in `context`console.log(context['user preferences']['favorite-color'])}
The APIs need some consideration and fleshing out, but note how the only times where URLs are specified are in the links themselves, and in the OPTIONS response (because it, too, includes links.) If the links were to change, the application would still work because it's not tied to URLs, it's tied to semantics. (Of course, if the semantics change, we be screwed.)
With mechanisms like these, we can truly start entering the realm of hypermedia driven applications.
Templating
I don't know whether the shell should inject these links automagically, or if it's something that should perhaps be controllable through the index templates. The latter obviously offers more flexibility, and certainly for some entry points perhaps not all services should necessarily be exposed for discovery? In those cases it may be better to offer control over this.
I would suggest we require that the templates must declare the services they want. Perhaps something like so:
#foreach( $service in $allServices )
<link type="service" title="$service.name" href="$service.url">#end
A bit of a mouthful, but at least it's explicit and I would think still provides the ability to just add services by name:
For dynamic discovery, if that is a thing we need or care about, I suggest we look into using a "well known URL", that is a URL under /.well-known/ which is then recognized as not something you may register in nap. For instance, /.well-known/zambezi/service-discovery might be such a path. Alternatively, we could expose this as a <link> as well, albeit we'd have to then get into reserving names such they can't be shadowed, which can get tricky.
Further thoughts
The address api would be re-usable in other contexts as well. Note that in the examples above, I never do the typical address(URL) call, but rather go to the (currently imaginary) link API which is at the root of address:
address.link('something')
Likewise, we may re-use this in responses and such. Let's say we got the user's preferences like so:
I propose that in order to discover services, we should leverage elements in the shell.
Optionally, add the
type
as a hint for the client to know what to expect:Address can pick these links up and provice a convenient JS API, something like thus:
(This would need fleshing out; how would you address links by rel, for instance?)
Why
title
and notid
? For a couple of reasons:id
is global to the page, and also used in determining document fragments; we should try and not interfere with thistitle
is more idiomatic;class
is also used, however this is typically to determine the kind of service it is and not so much which specific service it istitle
is semantically accurate, it is the logical name of the serviceOptions
Services could respond properly to
OPTIONS
requests such that clients may know what their options are with this service. We could leverage this in address to prepare requests. For instance, consider the following service:If address sends an
OPTIONS
request to this service, it could return a response similar to the following:Furthermore, the service could generate a body and send that to us as well, and so long as address can understand the body (and we can make it) we can prepare convenient APIs client side for interacting with these services. Here's an example of such a response from the fictional user preferences service:
From this, address can deduce that there are three meaningful APIs available for further exposure in JS: GET, POST, DELETE. The GET is simple (declared by the
Allow
,) header it's just a GET ofhttps://luser.example.com
, and can be exposed in the client as such:For the form, we may do something like so:
Additionally, using the hypermedia constructs we've experimented with in the developer site, one may do something like this:
The APIs need some consideration and fleshing out, but note how the only times where URLs are specified are in the links themselves, and in the OPTIONS response (because it, too, includes links.) If the links were to change, the application would still work because it's not tied to URLs, it's tied to semantics. (Of course, if the semantics change, we be screwed.)
With mechanisms like these, we can truly start entering the realm of hypermedia driven applications.
Templating
I don't know whether the shell should inject these links automagically, or if it's something that should perhaps be controllable through the index templates. The latter obviously offers more flexibility, and certainly for some entry points perhaps not all services should necessarily be exposed for discovery? In those cases it may be better to offer control over this.
I would suggest we require that the templates must declare the services they want. Perhaps something like so:
A bit of a mouthful, but at least it's explicit and I would think still provides the ability to just add services by name:
Or something to that effect.
Dynamic discovery
For dynamic discovery, if that is a thing we need or care about, I suggest we look into using a "well known URL", that is a URL under
/.well-known/
which is then recognized as not something you may register in nap. For instance,/.well-known/zambezi/service-discovery
might be such a path. Alternatively, we could expose this as a<link>
as well, albeit we'd have to then get into reserving names such they can't be shadowed, which can get tricky.Further thoughts
The address api would be re-usable in other contexts as well. Note that in the examples above, I never do the typical
address(URL)
call, but rather go to the (currently imaginary)link
API which is at the root of address:Likewise, we may re-use this in responses and such. Let's say we got the user's preferences like so:
In
handleResponse
we may do something like this:Perhaps we can provide some more sugar to this as well:
Not vastly different, but the semantics are clearer.
We'd need to flesh out these APIs more, but I think we can start off simple with the service discovery stuff, then add on to this over time.
The text was updated successfully, but these errors were encountered: