Skip to content

Linking federation backend IDs to the full details of the backend #67

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
christophfriedrich opened this issue Apr 6, 2025 · 6 comments · Fixed by #69
Closed

Linking federation backend IDs to the full details of the backend #67

christophfriedrich opened this issue Apr 6, 2025 · 6 comments · Fixed by #69
Assignees

Comments

@christophfriedrich
Copy link
Collaborator

As far as I've penetrated this topic so far, I believe the only way to get details about a federation backend out of the client is the listFederation method of the Capabilities class:

/**
* Returns list of backends in the federation.
*
* @returns {Array.<FederationBackend>} Array of backends
*/
listFederation(): Array<FederationBackend>;

This gives an array of FederationBackend objects, which look like this:

/**
* An array of backends in the federation.
*
* @typedef FederationBackend
* @type {object}
* @property {string} url URL to the versioned API endpoint of the back-end.
* @property {string} title Name of the back-end.
* @property {string} description A description of the back-end and its specifics.
* @property {string} status Current status of the back-ends (online or offline).
* @property {string} last_status_check The time at which the status of the back-end was checked last, formatted as a RFC 3339 date-time.
* @property {string} last_successful_check If the `status` is `offline`: The time at which the back-end was checked and available the last time. Otherwise, this is equal to the property `last_status_check`. Formatted as a RFC 3339 date-time.
* @property {boolean} experimental Declares the back-end to be experimental.
* @property {boolean} deprecated Declares the back-end to be deprecated.
*/

This doesn't include their ID. But throughout the rest of the client, the ID is how backends are referenced, e.g.:

/**
* A list of backends from the federation that are missing in the response data.
*
* @public
* @type {Array.<string>}
*/
public 'federation:missing': Array<string>;

/**
* @typedef Collections
* @type {object}
* @property {Array.<Collection>} collections
* @property {Array.<Link>} links
* @property {Array.<string>} ["federation:missing"] A list of backends from the federation that are missing in the response data.
*/

So currently it's impossible to link the two, e.g. to meaningfully display the federation:missing list to users in the Web Editor.

I see two three four options to remedy this:

  1. Add the ID to the FederationBackend definition: @property {string} id ID of the back-end.
  2. Make the response of the listFederation an Object with the IDs as keys and the FederationBackend objects as values (or even an explicit Map<string,FederationBackend>).
  3. Implement a getBackendDetails(id) method that you can call with e.g. getBackendDetails("eodc") and will return the corresponding FederationBackend object.
  4. Change the signatures everywhere a list of backends is returned to not just return the IDs but the full objects, doing the matching internally.

Which is the best variant? Are there already examples in the client for solving similar situations?

@m-mohr
Copy link
Member

m-mohr commented Apr 7, 2025

I think we should implement 1, 3 and 4.
To avoid a breaking change, we should probably implement 4 in a way that it's a new/additional property, maybe with missingBackends as a name.

I think I'd implement both getFederationBackend(str) -> object and getFederationBackends(array<str>) -> array<object>.
This way you can just pass the federation:missing array from jobs, services, etc. directly to that function and get an array with all resolved objects back.

@christophfriedrich
Copy link
Collaborator Author

Initially I agreed with you and started to implement that, but realised that then we must/should also change all the vue-components that currently expect a federation prop in object form. So it would be a breaking change there. And at the cost of increasing the gap between how the API spec delivers stuff and how the tooling expects stuff. Do you think 1,3,4 is still the best approach anyway?

@m-mohr
Copy link
Member

m-mohr commented Apr 9, 2025

listFederation can still be used to populate the federation prop. Why would this be breaking?

@christophfriedrich
Copy link
Collaborator Author

Situation:
Backend delivers object form (nothing to change about that).
JS client converts into array form (the suggestion here).
Vue components expect object form (current state).

That doesn't work out. We have to change either the JS client or the Vue components.

Or use the Web Editor sitting between the two, it could of course convert back to object form to resolve this. But why convert back and forth. It would be nicer to just pipe it through. Which would be an argument to realise option 2 instead, so that object form is used everywhere.

But I understand that from the perspective of the JS client alone, an array is much cleaner when returning a list. So the other idea was to change the Vue components to accept the array form, to save the additional conversion. But that would be a breaking change in the vue-components, as there the federation prop definition is already published as:

federation (object): The data of the federation property obtained from the capabilities.

One pill must be swallowed, just which one?

christophfriedrich added a commit that referenced this issue Apr 9, 2025
If coming from a spec-compliant backend, `this.data.federation` is an object, so the function used to always return the empty array. The code now transforms the object into an array, and also adds the former object keys to each item as an `id` property.
@christophfriedrich
Copy link
Collaborator Author

As discussed earlier, I now implemented it so that the JS client converts it into array form and the Web Editor converts it back. This way each tool can stay true to what makes most sense for itself and the extra work in the Web Editor really is just one line. (Probably I even could've gotten it from somewhere in the desired form already, but those fields may be private and I just found the way through listFederation the nicest as it's most explicit and kinda "the official way".)

@christophfriedrich
Copy link
Collaborator Author

I just also implemented the helper functions as I think they are very nice to have. I added ById / ByIds to the function names you suggested, in analogy to the well-known document.getElementById etc.

I hope the signatures are correct with the | undefined cases.

IMO, with this, option 4 can be considered solved too, as users can easily pass any string array through those functions now to get all the details they could possibly want. Plus what I wrote up there suggested that the JS client would return arrays of ID strings, but in fact it already returns Array<FederationBackend> everywhere, except where API responses are passed through and that obviously shouldn't be interfered with.

m-mohr pushed a commit that referenced this issue Apr 11, 2025
* Fix listFederation, add `id` property (#67 option 1)

If coming from a spec-compliant backend, `this.data.federation` is an object, so the function used to always return the empty array. The code now transforms the object into an array, and also adds the former object keys to each item as an `id` property.

* Fix docs (closes #68)

* Fix JSDoc syntax

Thanks automatic tests

* Fix listFederation changing raw data

see https://github.com/Open-EO/openeo-js-client/pull/69/files#r2036254956

* Add helpers for retrieving backend details (#67 option 3)

* Update changelog

* Strip "ById", change "undefined" for "null", fix syntax errors

* Never return "null" in getFederationBackend(s)

see #69 (comment)
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

Successfully merging a pull request may close this issue.

2 participants