-
Notifications
You must be signed in to change notification settings - Fork 0
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
Should Siren be using absolute URIs? #75
Comments
I'll try keeping things respective to particular paragraphs and in order so we have a somewhat clear correspondence for these notes. Completely agree and have nothing to add. This is true and one of the things I remember when figuring out siren the first time. They don't specify if URL encompasses relative and absolute URIs. In the end, I took a note from the URI RFC and collection+json's thought process that any relative URIs would be RFC style appended (see https://hackage.haskell.org/package/network-uri-2.6.1.0/docs/Network-URI.html#g:5 for more details). The reason we relay on relative links in the siren document is due to the difficulties in crafting an absolute URI from a service. We can go with the straight-forward: I'm configured with my base URI and will prepend it to all URIs but then we break if we move the service or otherwise change it's name and forget to update this parameter. Trying to automatically deduce this information is also tricky at best. Getting the host portion is generally straight-forward: grab the host header in the HTTP request, but what about the scheme? I may be behind an SSL terminating proxy of some sort and never know that SSL is in play but my users will have broken URIs if I don't specify it. I would like to consider that all collection+json URIs that are received as part of the API should be forced to be absolute but that means that the source of that information must be forced to provide an absolute URI. I still contend that any non-local relative URIs are a bug that need to be rooted out. For example in the document at #73, the race and discipline links are non-local and should not be relative. I also believe these are the relative links we are actually having problems with. These are relative because the API allows the client to submit a relative URI when creating a character. This should not be allowed. With only storing absolute URIs the problem is mitigated as any relative references will be local to the document requested and can proceed as outlined previously. Let me know if this makes sense as I believe it fixes the HTML validation problem as well. The collection server is unaware of the authorization but I'm not sure that's what you're asking on this one. I will simply refer to the earlier statements on determining the absolute URI from inside the API. We could but I don't believe that is necessary. We should be allowing the user to select a race or discipline and then using the request URI and the response URI craft the absolute URI that is submitted to the API. This is why I've been repeatedly saying the API should be validating this submission. It also corresponds to your HTML uri type being an absolute URI. I'd rather not make the assumption that the default list of races and disciplines are the only options. Having a way for a user to specify their own absolute URI to a valid and parseable race or discipline is a nice way for them to customize their game. So ensuring that we only submit absolute URIs is very desirable. I've outlined where relative URIs are preferred due to ease of implementation but everywhere else I'd want to use absolute URIs. Any URIs sent from the client to API should be absolute which will mediate a lot of the issues we're seeing right now. Let me know what you think of this rambling response, but I think we agree just need to make sure we picture it the same. |
Yes, I believe this is exactly the main issue. For now I will create characters using absolute URIs, and scrap the current ones I am developing with since they are malformed. Because the HTML5 form types (but not necessarily validation, for example can you specify optional fields?) are dictated by Siren, what a discipline and race turn into at the form level is a text input with URI pattern validation, and I don't think we want to make users type in URIs. I suggested a select input with the options provided by the discipline and race collections, and this is also not something apparently described in the Siren schema. Of course we could add an option for manual URI input for customization. Which leads to...
Can you give an example of how this could be derived with the current Characters entity? Of course I want to send absolute URIs to the API, even though I get relative URIs from the collection items. What I have is this:
These items would become the values in the form input, as described above. Since we do not want to have users type in URIs (our URIs, not custom), right? So at this point when the form is submitted I have a race field with a value of The proposed implementation, as far as I can tell, is that the client remembers the HTTP Host of each requested link. So for example when I request the disciplines and races collections, I could actually be saving these as a product of their host and response, like A bit of work, but I think it makes sense. It's just that this is something the client is assumed to implement, and not something the Siren relations make clear. |
I believe delete is implemented so give that a go for removing the characters you've created. Otherwise, let me know and I can purge them from the datastore. I'd have to check on optional fields, but I believe so. I think an option of typing in a URI should be available but the drop down or other selection with our list of defaults should be preferred. Hmm, does purescript have similar URI handling to Haskell? In Haskell I'd simply say the following, and fix any ensuing errors in either URI. item `relativeTo` collection This would result in (for your given example): That approach sounds reasonable but smells funny at first glance. I'd have to see an implementation to give it a full vet. Unfortunately, yes, siren does not make this clear but we are following standard relative and absolute semantics from URIs and other document types. So it shouldn't be too bad and should be very portable to other MIMETypes if we so choose. |
So I looked at a couple of ways to force the API to handle this and right now I'm leaning towards a Valid type that can wrap other types to show they've been validated. class Valid a where
valid :: a -> Validated a I'm thinking a functor and applicative instance make sense for this but not sure about monad yet. What do you think? |
-| This issue has not been updated in 90 days. It will be closed in 90 days if no further activity occurs. Please respond if you would like to keep it open. |
Right now the client knows one absolute URI for this API -- one which points to the correct API environment. This is used as a base to resolve all relative entity links like
/characters
, which in this example is acceptable because this is the root entity and the client needs to know this entry point at the bare minimum.However, the Siren spec appears to not have much to say about relative URIs. And the current Siren implementation is relying on relative URIs in most links. Which leaves us to our own devices for resolving links in the client. Of course it's a solved problem for any Siren entities coming from this API because the client has the host hard-coded and can append relative URIs to this host, but CollectionJSON links are using relative URIs and the client does not know their host.
My initial solution was to tell the client the base absolute URI for Collection links, just as we do for Siren links. This was deemed unacceptable because we require the client to know things that Siren is not telling it. The proposed solution in the API gives absolute URI links to collection relations on the root entity -- which are helpful insofar as the client can extract the host and append it with relative URIs to resolve links. Or the client can use these absolute URIs to fetch the collections, cache them in the client, and resolve links by querying the cache via relative URIs (which map directly to the
href
property on collections). It appears this latter behavior was intended for the client to implement. But in both approaches it means we still have to use relative URIs on character creation, in violation of theurl
type defined on thecreate-character
action fields.I believe I see the problem with the CollectionJSON implementation, since items are static and their hrefs cannot be determined at runtime (a collection doesn't know its environment). Which means we would need distinct collections for each environment? I admit this does seem tedious, but isn't this how it should be if every environment has its own audience? Or is the collection server exempt from this?
Could we solve this with another Siren relation? Something that tells the client a link must be looked up in a collection and not resolved via its href? And then we must remove the
url
type from character disciplines and races, perhaps making them simple strings. In this case the validation for character creation is handled implicitly because the client will only let users choose values from the collection (e.g. in a select dropdown), so URI validation is moot.Should we attempt to use absolute URIs everywhere? It does make the client easier to implement, but I'd like to know your thoughts on what the major obstacles are.
The text was updated successfully, but these errors were encountered: