-
-
Notifications
You must be signed in to change notification settings - Fork 280
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
Submitting both user and instance data via both the uri and message body #108
Comments
@awwright @Relequestual @jdesrosiers @slurmulon @Anthropic Any reaction at all to this? Am I the only person who has ever wanted to try to make this work? What alternatives am I missing? |
@handrews would an accurate TL;DR be that you want to define body data instead of just a querystring in links, but also type define the params? Regarding alternative requirements, from a UI Schema perspective one issue I find is that we need to be able to define data that is not added to the model represented by the schema, for example, you have a data set that is made into a wizard stepper sequence when the form is defined, the details of the wizard's current workflow step is not part of your model, but you want it in the uri, not in the content sent to the server. My server processes the entire data set sent to it, I need an additional scope that is not in the main definition to run conditions against. Almost like a scope for model and one for state. I guess being able to define what goes in the body would be useful for that. PS. Still unsure why links is an array, anyone know? Doesn't make sense to me, you don't want duplicate links and you need a rel, so why not make that the key in an object so it can easily be referenced. |
There are several link relations from various RFCs that specifically state that they can appear multiple times. Of course I can't remember any of them off the top of my head, but I assume that's the reason. It's a bit annoying for the common case, I agree. (I'll reply to the main points once I've had a chance to think through your example a bit more). |
@Anthropic if I understand your UI example correctly, your wizard sends a resource representation to update at each step, but each step also needs to send information that is outside of that representation? So the representation is sent in the body, and the other data goes in the URI? This is similar to what I'm talking about, and may even be the same in many cases. For me, anything that goes in the URI is part of resource identification. So URI query parameters that implement filtering and pagination of collections are identifying a subset of the larger collection. I suppose such parameters could identify states in a workflow as well. HTML provides only one direct avenue for user input, and HTML forms put that input into either the URI or the body. But I don't see a reason to preserve that either/or behavior in an API. I have frequently needed to interact with both, as the URI and the request body serve different purposes.
I'm not sure- what does "type define the params" mean? In an API, start from an entry point resource, and follow links, interacting with the various resources we encounter. We usually send representations of those resources back and forth, or (in the case of patching) documents related to the representation in some way defined by the media type being used for patching. Occasionally we send data that is less directly related to the resource, and in HTTP this is done using POST. What I've found missing in all hypermedia API systems that I've tried to work with so far is a comprehensive system for mapping data from resource A's representation into both the URI for related resource B and into the request body that is sent to resource B. The last system that I worked with adapted and extended the templating from JSON Hyper-Schema (based on #52), which solved the problem of mapping into the URI, but did not have a solution for mapping into the request body. This turned out to be a major flaw in certain workflows, breaking what was otherwise a very nice HATEOAS-based programming experience and making developers do unnecessary work to pick data out of resource A and stuff it into the request for resource B. In truth, the relation from A to B already dictated that behavior, we just did not have a mechanism to capture that and use it. Does that help at all? |
JSON Schema gets its link listing form from the HTTP Link header. But other JSON-based formats follow an object based approach, see #124 that I just filed. |
@handrews "type define the params" is that in the current link you could have params "wahtever/{id}" but you seem to use the hrefSchema to define what that id would actually need to be or would be in the case of the relative pointer. That's what I meant by that. @awwright You're awesome. |
Correct. We were already implicitly defining it by the schema of whatever the "id" property was. This allows for two things: Changing where to look up "id" using a relative pointer, and allowing explicit specification of the schema. Even when there is an implicit schema based on the instance property used to resolve the variable, in the case of complex schemas with "allOf"/"anyOf"/"oneOf"/"not"/"dependencies", extracting the correct schema automatically to use with user input can be very challenging. So it makes it much easier to implement and more clear to read if supporting validation of user input requires an explicit schema. Explicit specification of URI template variables accomplishes two other things: supporting user input for URI variables through the same mechanism as instance-based URI variables, and completely separating the URI variable mechanism from the request body mechanism. |
@awwright I'm trying to stay out of #96 at your request, so could you comment here about how you would fit this use case into your views on |
PR #129 is one approach to implementing part of this ( @awwright suggested an alternate first step during an IRC combination, of Just writing this here to keep any other readers up-to-date on various ideas of how to move this forward. |
This sounds reasonable to me! |
Was there some attempt to fix this problem? I'm not totally clear. Seems like it's still a problem. |
#179 is a first step. There's more to it, but that's the part that is targeted for draft 6. |
@handrews @Relequestual I would find this feature highly valuable for the reasons described above, generally:
The old solution to this (and this is from memory and may be misguided due to lack of information) is where you have URI template variables that are associated with schemas by encoding a JSON Pointer into the template variable itself. I'm not sure if this is truly supported, so please ignore this example if so:
So yeah, the new/proposed approach a much needed improvement IMO. Regarding the state of things:
What concepts need working on the most? What are the biggest concerns? |
@slurmulon PR #228 (which was earlier submitted as #179 but bogged down as it took on too much) ONLY adds "hrefSchema", and "hrefSchema" may only use normal schema constructs- no relative JSON Pointers (with or without "$data"). It leaves everything else alone. If there is an "hrefSchema" and external input is supplied, that is used first, but for everything else the existing URI Template preprocessing and resolution from instance applies, and then "method" and "schema" work as they have been. Using "hrefSchema", "method": "get", and "schema" all together is a little weird, but the PR establishes a clear order of actions so the result is unambiguous. @awwright is skeptical of both "$data" and JSON Pointers, an @epoberezkin has is own issues with JSON Pointers as well. I don't want to derail this issue into a discussion of those concerns: There are (or should be) issues devoted to each. If we can agree on all of the necessary tools, then we can fix the rest of this. It might take a few steps, though. But reaching something that is the functional equivalent of the example in this PR is my overall top priority for hyper-schema. |
I'm going to go ahead and close this, as the key point was addressed by splitting
In the meantime, we could use fewer gigantic confusing issues lying around :-) |
[Edited for changes made between #159 and #179]
[Edited to replace
hrefVars
withhrefSchema
based on later discussions]The purpose of this issue is to explore the limitations of the current draft's usage of
method
,schema
, andhref
(in terms of resolving template variables). There are ideas here that could become a proposal, but I am not directly proposing anything in the example schema. I'm really just trying to find a consensus on the limitations.The main point here is the need to both specify URL parameters and a message body. The API has events and invitations. The invitation collection can be filtered from either the event perspective or (via email address) the invitee perspective. I did not provide a schema for invitees as it made the example too long without adding anything.
Since the query string is as much a part of the identifier as the path components, this API treats
/invitations?event=1234
as the collection of invitations for the given event. The API supports creating invitations for event 1234 by POSTing to that URI, just the same as it would for a URI of/events/elements/1234/invitations
. However, not all of the fields needed to create an invite can be a part of the URI, so a creation also takes a message body providing the remaining parameters.The current
href
specification does not allow it to define user input. But ifschema
is used for the body, there is no other mechanism for getting user input into the URI. This example useshrefSchema
as a way to map the URI template parameters to a schema and/or a value from the instance. This is to help illustrate the two routes of user input, not proposehrefSchema
as necessarily being a solution.hrefSchema
is a schema which treats the template variables as if they were properties of a JSON object. Each variable property's schema is used to validate "user" input (which may or may not be from an actual human user). It can use$data
withdefault
to take a default value from the instance when no user input is supplied. To implement the current behavior of only resolving from the instance, you would use a schema like this:For convenience, the above can be specified by just giving the
"0/email"
relative JSON pointer instead of a schema (this is what you will see in the example). [EDIT: originallyhrefSchema
washrefVars
and did not quite use regular schema syntax. Now thathrefSchema
is a regular schema, the shortcut might be a bad idea]. The default behavior for template variable{foo}
is"hrefSchema": {"properties": {"foo": "0/foo"}}
(which replicates the current behavior).I am also not advocating for or against this specific design of collections and individual resources. It was constructed to illustrate my points. You could get around some issues by redesigning the resources, but aside from expecting APIs to not blatantly abuse protocols, I do not think that hyper-schema should be opinionated about resource design.
Given this schema, I should be able to do something like this (separate params and data arguments lifted from the design of Python's "requests" library- again, not insisting this is the solution, just trying to illustrate the challenge):
So in this example, there are several combinations of data sources and destinations:
Currently, this cannot be expressed in hyper-schema. Should it be possible? If we get agreement on that, we can talk about how to do it.
The text was updated successfully, but these errors were encountered: