Skip to content
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

Endpoint to fetch workflow type #259

Closed
mkhraisha opened this issue Feb 8, 2022 · 14 comments
Closed

Endpoint to fetch workflow type #259

mkhraisha opened this issue Feb 8, 2022 · 14 comments
Assignees

Comments

@mkhraisha
Copy link
Collaborator

We probably should have an endpoint where you can fetch what workflow types your implementation supports.
something along the lines of GET workflows

@mavarley
Copy link
Contributor

mavarley commented Feb 9, 2022

I strongly agree this type of discovery is a requirement - and beyond just "supported workflow endpoints", discovery must include some definition on the protocol supported by those endpoints.

In conjunction with that, I think it is vital to avoid creating the next WSDL. Clients to this API and its discovery need clear, normative guidance on how to interact with discovered endpoints (and when not to). Leaving /exchange endpoints too open to server implementor's whims implies massive amounts of work on the client, or crushes broad/open-world interoperability. And if broad, open-world interoperability is not a goal, then I would argue the "workflows" pattern is out of scope of this API (but to be clear, I want to support the open-world interop approach if we can).

I'd like to keep this Issue focused on workflow endpoint / type discovery, and open another issue/pr on the protocol discovery problem once this issue is resolved if folks agree, to contain the discussion a bit.

An example structure for GET /workflows or GET /exchanges (depending on REST patterns) may be to map the exchange id to a protocol type, or url defining the protocol. Clients must recognize the type as a supported protocol before calling the endpoint (or its just gonna bomb anyway).

GET /workflows HTTP/1.1

200 OK
Content-Type: application/json

{
    "credential-refresh" : "GenericCredentialRefresh2020",
    "userinfo" : "OpenIDConnectCredentialProvider",
    "my-salad" : "https://dev.example.com/oas/salad-protocol/v2/my-salad.yml"
}

This issue I think should define acceptable "types" on the RHS, and the next issue should provide guidance on the contents of these types/references - what MUST be in a type definition for clients to successfully operate in this pattern?

Thoughts?

@OR13
Copy link
Contributor

OR13 commented Feb 15, 2022

You probably want to build in support for pagination:

GET /workflows?limit=10&filter=...

200 OK
Content-Type: application/json

{
   "total": 1,
   "items": [
    {
        "credential-refresh" : "GenericCredentialRefresh2020",
        "userinfo" : "OpenIDConnectCredentialProvider",
        "my-salad" : "https://dev.example.com/oas/salad-protocol/v2/my-salad.yml"
    }
   ]
}

@mprorock
Copy link
Contributor

You probably want to build in support for pagination

There are some pretty normal conventions for this that we can take a stab at in a PR

@OR13
Copy link
Contributor

OR13 commented Feb 15, 2022

@OR13
Copy link
Contributor

OR13 commented Feb 15, 2022

relevant DIF Specs:

Use Case: Discover the credentials and flows this issuer supports, then automatically obtain a credential from them, by presenting them other credentials.

@mavarley
Copy link
Contributor

Thanks Orie; I'll have a look at Hydra.

From first scan, and in response to the Credential Manifest and Presentation Exchange, I was thinking of something more generic; but I am open to feedback before I put together the PR.

What I had in mind was a JSON object where:

name -> exchange-id (path) name
value -> spec definition string

where the Client MUST recognize the spec definition string as something it can support (if it expects to execute on the exchange).

The spec definition string points to a "defined" spec; and those specs may be fluid and dynamic, or more prescriptive. For example, MediatedRefresh2021 (as referenced in VC Refresh ). Or maybe CredentialManifest (referenced above) as a more generic flow; or someone defines a more prescriptive MediatedRefresh-WithCredentialManifest which takes the general Credential Manifest spec and puts additional boundaries on it for a specific purpose...

My goal/approach is that a Client (Holder) should be able to determine what protocol the endpoints support, and if they recognize that protocol, before calling them. This does not necessarily guarantee Client success; maybe during the exchange the Client discovers it cannot provide the necessary Cred... but at least it was able to communicate with the server and obtain those expectations.

I would like to avoid Clients from having to implement too much logic at this stage of "discovery" - they either recognize and support the protocol or not.

Open to other approaches on how Clients can quickly determine what to do with an endpoint.

@mavarley
Copy link
Contributor

You probably want to build in support for pagination

There are some pretty normal conventions for this that we can take a stab at in a PR

I also think we can add query params to tweak the response after we know the contents of the response... pagination and filtering etc...

Quick rationale check; pagination is important because? I haven't seen it in other discovery protocols, but don't take that as me saying its a bad idea (and I have not seen all discovery protocols either). Just looking for the reason. Examples could be "in traceability world, we have thousands of workflows..." or "as a Client, I'll have an idea of the exchanges I support and don't want to receive and process the entire set..." ? I dunno, help me out :) supporting query parameters complicates server implementation.

@OR13
Copy link
Contributor

OR13 commented Mar 21, 2022

@msporny sorry, I can't lead on this one... perhaps @mkhraisha or @mprorock or @mavarley would be able to define these endpoints?

@OR13
Copy link
Contributor

OR13 commented Mar 21, 2022

Here is a better pagination example to kickstart the process:

GET /workflows?limit=10&filter=...

200 OK
Content-Type: application/json

{
   "total": 1,
   "items": [
    {
       "id": "https://example.com/123" | UUID,
       "type" : "GenericCredentialRefresh2020",
    }
   ]
}

@mavarley
Copy link
Contributor

@OR13 - I am able to define the endpoints, but I've asked for rationale as to why an endpoint used for automated discovery needs pagination - and if filtering is also required as I will include it in the same update.

From my POV, I don't see such a huge volume of endpoints that the payload would be cumbersome for clients to manage (ie, the JSON response is reasonable enough in size that pagination is not required). If this is for UI display I can see the need for pagination but it is not something I had considered. If it is for finding an endpoint, then filtering may be more appropriate.

Requiring pagination adds complexity and testing to the implementation which I just want to make sure we have a rationale for.

What do you have in mind?

Thanks.

@OR13
Copy link
Contributor

OR13 commented Mar 21, 2022

@mavarley its not that it needs it now, it's that you shouldn't assume it never will... and your JSON should account for that in the future.

@msporny
Copy link
Contributor

msporny commented Mar 21, 2022

@mavarley its not that it needs it now, it's that you shouldn't assume it never will... and your JSON should account for that in the future.

Yes, this comes up time and time again. As a (bad) example, IBM and Oracle went as far as to define one for the Linked Data Platform HTTP API work:

https://www.w3.org/TR/ldp-paging/

I don't think we survive this work without one... and we should look to Twitter/Github/etc. for inspiration.

@dlongley
Copy link
Contributor

dlongley commented Mar 21, 2022

Presumably, any client using this interface will be enumerating / continuing a query against the same deployment. Given that, we may allow implementations more flexibility in their database choices, etc. by expressing cursor information using an opaque next value string and whether or not there are more results:

{
  results: [/* { result one } */, /* { result two }, ... */],
  cursor: {
    next: <id of next value | page number | meaningful to implementation>,
    hasMore: true
  }
}
GET /issuers?controller=<some DID>&cursor=<next value>

@mavarley
Copy link
Contributor

Work and discussion is captured in PR #268 - closing this issue.

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

6 participants