-
-
Notifications
You must be signed in to change notification settings - Fork 21
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
Request linked resources directly from returned responses. #103
Comments
Great news to hear notification UUID is passed back in a header. I always thought looking up the most recent notification (as I do in Acquia cli) was a bit frail. I think a good option here for this library would be to retrieve the UUID and pass it back as a property of the By the way, is this header reflected in the docs somewhere so I can refer as I build? No dramas if not but would be good if there’s a recommendation on implementation/stability/coverage. |
I had a first pass at this in #104. I've passed through the response headers by adding them to the body as One thing I have also considered doing is parsing the Before I look further into this, I'd love to see whether the Acquia API team would consider changing the API or augmenting in such a way that any operation would also pass back the notification UUID in the response as that seems to me to be a cleaner way to handle this. e.g. for the creation of a database. Current
Proposed
|
The more I look at this, the more inclined I am to either parse the Unless there's a more clean way to pass this header through (which may require quite a large restructure of the codebase), this might just be something that we delegate to dependent libraries (as Acquia Cli does). My main reasoning behind this is to keep this library as simple as possible without making on-the-fly adjustments to the responses from the API (which I've realised my patch does). I could potentially make a public method to retrieve response headers, however to me that feels like the wrong way to go forward with this library. I'll leave this issue and PR open for now as there might be some useful input that I've not considered, but currently I can't think of a clean solution - especially when there is a workaround, albeit a slightly dirty one. |
Hi @typhonius ! I think it could prove helpful to add linked resource retrieval: Cloud API uses HAL+JSON as its response format to facilitate traversing the API via related resources (HATEOAS). Something like this might work to retrieve the notification in this case, for example: $response = $client->deployCode();
$notification = $client->getLinkedResource($response->getLink('notification')); Or in other contexts, let's say you wanted to get the application that contains an environment: $environment = $client->getEnvironmentById('env-id');
$application = $client->getLinkedResource($environment->getLink('application')); That said, I've noted internally that we should consider just embedding the notification in the response, to avoid having to make the additional request to retrieve it. While this would save one request, we expect that the notification resource to be polled multiple times as the operation completes, so I'm not sure how much value it'd be to save that initial request. Let me know what you think! |
Thanks for that extra context @itafroma. You’ve given me a good idea about how we can make this happen. Because all tasks that would effect a change causing a notification get turned into an I’ve also decided to explore creating a new
I’m not sure yet how I’ll go about actually making the call to retrieve the linked resource but that’s just an implementation and organisation puzzle. |
I've created a first pass in #111 that definitely won't pass tests. I've branched from #108 so the PR will look extra-large until that is merged in. Functionality-wise we're looking at something like the below:
|
And for notifications (the original point of this issue), we'd be looking at something like:
|
Very cool! Looks like you implemented what we expected (and support) in #111, but to clarify regarding how links work:
And just a word of warning, we want all operations to have a notification link, but there are still a few gaps, mainly around teams and permissions (whose operations all resolve instantaneously). |
Thanks @itafroma I think what's been written so far aligns with your 1st and 2nd bullets nicely. I also think your final comment is taken care of because I ended up not tying notifications to For your second point, can I safely assume that there will only one (currently named href) property returned per linked resource e.g. databases->href->$link, environments->href->$link etc. If so, I can do something like the below that will allow the library to get the link even if the word 'href' is substituted for something else. If the link may have multiple properties in future e.g. databases->href->$link and databases->foo->$link then we'll need to think up a new way of enumerating links. If there's an easier way of parsing this (while taking into account href may change to a different word) then I'd love to put that in instead. The solution below works but feels a bit unclean.
|
This is a bit cleaner (amazing what you can find on StackOverflow) but I fear it suffers from being a bit opaque to someone coming in fresh (or me in 2 months after I've forgotten why I did it) so may either need further cleaning up or heavy documentation.
|
We adhere to the JSON HAL draft spec, so you can assume The only weirdness you might run into is in parsing certain types of templated links, like the ones you see for pagination and filtering in collection responses. Those are designated with a
It may be worth supporting those as an optional parameter: // Retrieves https://cloud.acquia.com/api/applications?limit=10
$limited_applications = $db->getLinkedResource($response->getLink('limit'), [
'limit' => "limit=10",
]);
// Retrieves https://cloud.acquia.com/api/applications
$limited_applications = $db->getLinkedResource($response->getLink('limit')); Though it gets tricky because this would be a case where the link name doesn't tell you the correct response. Now that I think of it, there's a number of link names that are contextual in what they return:
|
Okays, so this makes sense to get the notification object.
One question (may be a separate issue) is how to refresh that notification so that you can loop until "completed"… We probably don't need it on a lot of objects, but notification is meant to change frequently, so having a method on the object to refresh or even to |
The $notification = $notification->getLinkedResource($notification->getLink('self')); |
I think for the purposes of this library, implementing a watch/refresh function is probably best left to other packages extending it. The reason for this is that there will be a number of different configuration parameters that users may wish to alter for themselves e.g. how often to check a notification, how long to wait until a task is considered timed out, or if we even bother waiting for a response. I feel like it would go beyond the scope of an SDK to determine how the user wishes to interact with the API beyond making requests and receiving responses. I'd be willing to reconsider if there's a reasonably simple, non-prescriptive way of doing it, but it feels more natural to keep it in a dependant library. I've done similar in the logstream package for specifics around connecting to that service (this library just gets the logstream connection details) and in the cli package (which handles waiting for notifications). Code for that is below if you want to pinch it for acquia/cli or another package. https://github.com/typhonius/acquia_cli/blob/master/src/Commands/AcquiaCommand.php#L152-L221
It seems that the JSON HAL spec requires the href parameter so I'll put that back in. I've reread your message from earlier and realised that I misunderstood what you meant by the value being opaque - you didn't mean that the word 'href' could change but that the value itself could change. Since we're calling
I think your sample code below makes a lot of sense and will be relatively easy to implement, although I'll probably schedule that in a follow-up for this. We have access to
I'll need to have a bit of a longer think about how I make this work as:
My thought for self was that I could Ultimately however it would be beneficial to get linked resources from either though so I'll do some thinking of how I can alter things in a non-breaking way - perhaps this is where a trait would be useful... |
Ok, pretty mega restructure but I believe without any changes to end user code:
|
Commenting for myself later that it might be worth putting |
Is your feature request related to a problem? Please describe.
Some endpoints return a Notification UUID to allow for tracking the completion of an attempt.
For example, when you create a database backup or ask to purge Varnish cache, the response is that the process has started and a Notification to track.
However, the json body response only has a "_links.notification.href" with a full URL to the notification. To use the "Notifications" object directly, you need to have a notification UUID. In the body response, this would involve parsing the href URL to extract the ID.
There is also an HTTP header,
X-CloudApi-Notification-Id
, that is returned with just the ID which would be helpful.Describe the solution you'd like
It seems that having the ability to a) retrieve the UUID directly and b) have a semi-automated looping mechanism that can track the notification to "completed" or an error state.
The text was updated successfully, but these errors were encountered: