-
Notifications
You must be signed in to change notification settings - Fork 71
Implement PATCH request for FedoraResource entities #527
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
Comments
Just to flesh this out. What would the possible contents of the BODY of this request be? |
@whikloj It would be equivalent to what PATCH accepts for XML or JSON, but JSON-LD. So it would contain triples you want updated, but not the entire representation of the entity. Something akin to https://www.drupal.org/docs/8/core/modules/rest/4-patch-for-updating-content-entities, which shows you how it's done with HAL. |
Is it something like this? |
@ajs6f Not really. I was rolling with Drupal on this one. It expects enough info to load the entity (which is more than just an id, you need to know bundle as well), and then only the properties you want to get updated. There may be a little more wrapped in there, but couldn't tell you without more exploration. |
So funny story, this works for json right now. No actual work involved. I enabled PATCH with json and basic auth. Then I created a RDF Source with some name. Then I did
and lo and behold the name of the resource had been updated. If I don't pass the basic auth parameters you get a HTML page for access denied, but the headers are
Thoughts? |
So I'm guessing this is not going to work for json-ld format, nor does it care about the vclock parameter. The json-ld is probably something we need to develop centrally so it can be used by all the HTTP operations, but I'll look to adding a requirement for the vclock. |
@whikloj but if it works for JSON, most of the heavy work is done, good finding!. the JSON-LD part would just need to map back to JSON representation Drupal already knows of (which are the fields, most likely the way post is doing that) and then execute all the logic JSON already applies. Sounds easy, but for sure it can have more complications. Probably when that logic goes into the serializer this operation should work natively for json-ld also. |
Yeah, totally works right now. If we can't sort out the serializer in both directions before deadline, this is my fallback, lol. |
@whikloj It's tricky. There doesn't seem to be a way to really alter existing REST resources, per se. Just ways to register your own plugin instead of the default. It's akin to making your own custom controller but having it work under the guise of the Drupal's REST system. Maybe we could implement conditional updates with the version counter via middleware, but I haven't explored that approach enough. |
So what I am doing right now is just implementing Then pointing to my own class that extends the normal entity REST response class and just implementing my own This seems to be behind the serialization layer as |
@whikloj Precisely. If you can get at the headers and add the conditional part there, I think it'd be great and provide a seamless Drupal experience. I got pretty frustrated with it earlier and gave up on REST system, so maybe you're just the man we need to work through it. |
@dannylamb oh right I forgot that the vclock was a header 🤦♂️ This is going to need to be a routing alter, as the requirements are set on routes. |
Ok, I need some help here. This is what I know. If the vclock is in the request body, I can compare it once we start processing the actual PATCH. That isn't really the Drupal way as the check should occur before it, but we don't get that until the entity is ready. We can leave it as a header and perform a test like the CSRF-Token check, except that to validate the vclock we need to load the entity, to get the uuid to get the current vclock value. But (and this is my lack of understanding of the "Drupal" way) you don't have both the request and the entity at the same time. |
@whikloj you could have request and the entity at the same time. Worst scenario: at least enough data to load the entity base on the request. Can you point me to a piece of code/existing functionality you would like to extend? last idea, if you have the request object around, as we did in silex, you can further mash-it-up, decorate it, and add stuff to it (like an internal communication decive) only because the request object Drupal uses is not PSR-7 (inmutable) |
I got it, it took me a bit but I can just add the Request to the patch function signature and boom it is there. So I am closer. |
The version counter is passed as a header and is not stored on the entity, so it could in theory be handled totally before-hand. But yeah... that's the problem with the whole REST system, the plugins don't act until too far downstream. I think you can auto-inject Requests by just putting them in the function. |
HA! Ninja'd by @whikloj Good form. |
Before I get too far... Do we care about this warning showing up in watchdog and on the CLI when clearing cache?
Basically because I |
@whikloj easy or the complex answer? UPDATE: easier way $yourcontainer->get('request_stack')->getCurrentRequest(); And keep the signature intact (don't read after this block, your eyes will hurt) Easy (for me, not for the developer): We should care because it will fail on tests and it is not cool: breaks http://en.wikipedia.org/wiki/SOLID Complex (for all of us): You will need to extend from the same interface it is expecting and add methods that are missing/you need via private methods. It is basically duplicating code. Other option is creating internally a new object from the class you need by copying attributes from one (compatible interface) to another(the one you want) (code duplication sorry) or add/reuse some type of Trait. Can you share some snippet? |
Hi all, Okay I have gotten to the point where I have the JSON-LD patch at the ContentEntityNormalizer in claw-jsonld. There is all goes to hell, mostly because it does not seem to do anything with the @graph, it checks for a field with that name and dies on an uncaught exception. I'm going to push up branches to Islandora and claw-jsonld so everyone can see what I'm doing. I feel like I'm close, but not overly confident it this serialization land. |
Here is the comparison of my Islandora branch issue-527. This works for JSON, and is pretty good for json-ld. I get the header into the data (actually into the context) but the json-ld denormalizer might need adjusting or I might need to be putting the entity id and bundle id in different spots. Here is the claw-jsonld branch comparison, I tried to just get the entity/bundle to load and thought the rest would work...but it doesn't seem to. |
@whikloj I think what you are seeing is correct and expected. claw-jsonld never got to that part. All the coding was done on the normalizing/serializing part but not backward fucntionality was added, remember this code comes from a different dimension. If you are willing to give this next week some try, i will grab both your branches and do some testing tomorrow sunday to have something to share (no tests!) next week. Could need some guides to get to the same part/see what you are seeing and understand how you would like that part to behave. (and of course would need you to review my code and finally, maybe marge) Good work. |
@DiegoPino sounds good, just knowing that this part may not be functional before helps me out. I can work through some of it. I am wondering is should we be standardizing our JSON-LD before this...like should we transform whatever we get into expanded so we can only deal with one format. I also realized I have some changes, I injected a database connection to make a VersionCounter I should have just injected the VersionCounter. I'll play around with this and see what I can come up with. |
@whikloj want me to pull against your https://github.com/Islandora-CLAW/claw-jsonld/compare/8.x-1.x...whikloj:issue-527?expand=1 ? @Natkeeran pinging you here, because basically what @whikloj needs is the important json-ld to entity structure part (the one @dannylamb was asking you) from your POST generalized into claw-jsonld. @whikloj dhlamb: last question: how does PATCH works internally in Drupal if we are not using an query language like SPARLQ-UPDATE here. Does it replace values if the exist? (and how do we know if they exist in the same position?) or will that be always additive? |
@DiegoPino that actually isn't a PR yet. That was just some stuff I had tried in claw-jsonld. If you have something better, just open your own PR and if I have any suggestions I can pull against your PR. Regarding the question of how PATCH works internally, in the case of JSON it overwrites the values you send as long as you have permissions. In the case of JSON-LD, well we get to decide how it works. I have been trying to implement the functional tests for the FedoraResource Rest and those seems like a huge pain. I'll add in some simple kernel tests for the things I can think of and open a PR on Islandora. |
@DiegoPino If you're just using plain old JSON, it replaces entirely. So if you want to add you need to have all the old values plus your new ones. I believe the order in which you provide them becomes the order in which they are persisted and subsequently returned in GET requests. |
@whikloj Test what you can. Reach out if you want/need help. |
@dannylamb @whikloj @ajs6f @acoburn as discussed in IRC today, PATCHING linked data without clear semantics /query-update language is weird/complicated and prone to explode(or not work at all). Good for now of course to have this code, but good to know that if we are going to add this formally to the API in the future we or you all should discuss a lightweight php implementation of an SPARQL-UPDATE parser or going with something like what GraphQL proposes like (mutations) Again, not saying this should go in/into/or via PATCH (lol) into the MVP, and not saying anything at all more than: we will need to deal with this anyway in mid-term |
So now my tests are failing due to
That seems to be because the PlaceHolderResolver in typed_data expects the value to be text and we are sending an array array (
0 => 'activemq:queue:islandora-indexing-fcrepo',
1 => 'activemq:queue:islandora-indexing-triplestore',
); So nothing seems wrong, these tokens are correct. But the resolver can't process the replacement, so the rule fails and the test fails. weird one. |
@whikloj it feels hard to say, but rules and typed data are pretty much beta with some tastes of Alpha, but so are we also, we have to live with it. Also: i thought there was a typo and a bug (says Mr. typo here) in the spoy your test code was failing: $placeholders_by_data = $this->placeholder**Resovler**->scan($value); It is consistently all around the file, so not a bug but a typo "Resovler". Which helps explain maybe why that method is badly implemented, maybe lacked enough reviews... (explained further down because RULES seems to have a bug there) The Confirmed by/ allowed in
for its In less number of words: There is a bug in RULES there. |
@whikloj 👀 And that explains/should/could explain why you are lacking certain triggered events? |
@DiegoPino @whikloj Have you considered applying the patch and seeing if it works? If that fixes the testing issue, you should bump the issue on Drupal.org and see if you can get some action. |
@dannylamb the patch works, but will likely be rejected because the coding is lazy and because well nobody is assigned to test it... I mean, there are for sure better ways to code that and typecasting to array before iterating seems more optimal, anyway, it works. But also, the issue has been open for 5 months. |
@DiegoPino I think that we should be contributing back to Drupal modules anytime we can be. As part of the open source Drupal ecosystem, I think its important that we do so, and that we shepard our patches though review and get them landed in the appropriate modules. Especially now that we are trying to bring Islandora much more into the Drupal ecosystem. In this instance if there is an issue, and the patch isn't great, we should probably take the patch and submit one that is more likely to get accepted. From what I've been seeing a lot of D8 modules are actually doing most of the development on Github, with DO tickets (like we are doing with JIRA in 7.x). Rules actually has a repo here, with a fair number of PR against it (the repo is buried in the readme on DO). For these repos patches tend to linger, but PR are addressed more quickly. Which makes sense the DO patch workflow is pretty brutal sometimes. Maybe we could submit a PR with a better version of this patch, and tag the maintainer. Might get the issue fixed a little faster. For the JWT module I tracked down the maintainer on the Drupal IRC channel, and asked him about getting the patches I wanted landed in the module before I started working on them, because there were some pretty major changes there. He seemed happy for the help. |
@jonathangreen Agreed. And in many ways it's the path of least resistance and most karma to push changes upstream. Certainly beats re-coding already existing functionality elsewhere, which may seem easier at the time, but incurs technical debt in the long term. |
FYI, there's a PR to address this in Github: fago/rules#480 |
Implement an endpoint that accepts PATCH requests at
http://localhost:8000/fedora_resource/{id}
.The text was updated successfully, but these errors were encountered: