Why can't I reuse names from endpoints that have been previously deleted? For example, if I create an endpoint named "acme-cdn1", delete it, and try to create a new endpoint with the same name I get the following message: "Error, that endpoint name already exists." Is it necessary delete the entire CDN profile in order to reuse old endpoint names?
No, you cannot.
CDN endpoint is reserved for sometime once created. This is to prevent other people create CDN endpoint right after you delete your endpoint and get your traffic due to CDN setup take 3 hours +.
For example, let's say I created a CDN endpoint called myendpoint.azureedge.net and I was using it to streaming my pictures. And I deleted myendpoint.azureedge.net. Suddenly, you created the endpoint called myendpoint.azureedge.net. When you visit the url, you can still see my pictures even you already set the different origin.
Such operation will not be completed for at least two hours. In this case your CDN endpoint is not usable and you will be billed on the traffic which is not acceptable.
Related
I have this question in my mind for a day, I tried to do some reading from RESTful Web Services Cookbook and other stackoverflow posts, but still did not get a convincing answer to this question:
Assuming I have a database table storing relationships between two users, the relation represents that if user A is following user B (e.g. on Instagram/Twitter).
userId|userId
------|------
userA | userB
userA | userC
....
So now if user A would like to unfollow user B, then should this API be DELETE or POST?
In RESTful Web Services Cookbook page 11, it says:
"The DELETE method is idempotent. This implies that the server must return response code 200 (OK) even if the server deleted the resource in a previous request. But in practice, implementing DELETE as an idempotent operation requires the server to keep track of all deleted resources. Otherwise, it can return a 404 (Not Found)."
Does this suggest us to not use DELETE whenever we can avoid?
Thanks for any insight on this question!
DELETE is for deleting specific resources. So if DELETE is appropriate for you depends on if you have a single resource that 'represents' the follow relationship between two users.
For example, if you have a resource as such:
/api/userA/follows/userB
Then it could be said that this resource represents the relationship between the two. It has a unique url, so this url can be deleted at which point I would expect the relationship to be severed.
Building on top of Evert's answer, the DELETE method is suitable for your needs, as long as you have a resource that represents the relationship between two users.
The semantic of the DELETE method is defined in the RFC 7231:
4.3.5. DELETE
The DELETE method requests that the origin server remove the association between the target resource and its current functionality. [...]
The DELETE method is, in fact, meant to be idempotent, but your quote is fundamentally wrong when it relates idempotency with the status code.
As I previously mentioned in this answer, idempotency is not related to the status code itself. Idempotency is about the effect produced on the state of the resource on the server, even if the response for the subsequent requests are different from the first request.
Consider a client performs a DELETE request to delete a resource from the server. The server processes the request, the resource gets deleted and the server returns 204. Then the client repeats the same DELETE request and, as the resource has already been deleted, the server returns 404 and that's totally fine.
Despite the different status code received by the client, the effect produced by a single DELETE request is the same effect of multiple DELETE requests to the same URI.
Background:
I have a single page application that pulls data from a REST API. The API is designed such that the only URL necessary is the API root, ie https://example.com/api which provides URLs for other resources so that the client doesn't need to have any knowledge of how they are constructed.
API Design
The API has three main classes of data:
Module: Top level container
Category: A sub-container in a specific module
Resource: An item in a category
SPA Design
The app consuming the API has views for listing modules, viewing a particular module's details, and viewing a particular resource. The way the app works is it keeps all loaded data in a store. This store is persistent until the page is closed/refreshed.
The Problem:
My question is, if the user has navigated to a resource's detail view (example.com/resources/1/) and then they refresh the page, how do I load that particular resource without knowing its URL for the API?
Potential Solutions:
Hardcode URLs
Hardcoding the URLs would be fairly straightforward since I control both the API and the client, but I would really prefer to stick to a self describing API where the client doesn't need to know about the URLs.
Recursive Fetch
I could fetch the data recursively. For example, if the user requests a Resource with a particular ID, I could perform the following steps.
Fetch all the modules.
For each module, fetch its categories
Find the category that contains the requested resource and fetch the requested resource's details.
My concern with this is that I would be making a lot of unnecessary requests. If we have 100 modules but the user is only ever going to view 1 of them, we still make 100 requests to get the categories in each module.
Descriptive URLs
If I nested URLs like example.com/modules/123/categories/456/resources/789/, then I could do 3 simple lookups since I could avoid searching through the received data. The issue with this approach is that the URLs quickly become unwieldy, especially if I also wanted to include a slug for each resource. However, since this approach allows me to avoid hardcoding URLs and avoid making unnecessary network requests, it is currently my preferred option.
Notes:
I control both the client application and the API, so I can make changes in either place.
I am open to redesigning the API if necessary
Any ideas for how to address this issue would by greatly appreciated.
Expanding on my comment in an answer.
I think this is a very common problem and one I've struggled with myself. I don't think Nicholas Shanks's answer truly solves this.
This section in particular I take some issues with:
The user reloading example.com/resources/1/ is simply re-affirming the current application state, and the client does not need to do any API traversal to get back here.
Your client application should know the current URL, but that URL is saved on the client machine (in RAM, or disk cache, or a history file, etc.)
The implication I take from this, is that urls on your application are only valid for the life-time of the history file or disk cache, and cannot be shared with other users.
If that is good enough for your use-case, then this is probably the simplest, but I feel that there's a lot of cases where this is not true. The most obvious one indeed being the ability to share urls from the frontend-application.
To solve this, I would sum the issue up as:
You need to be able to statelessly map a url from a frontend to an API
The simplest, but incorrect way might simply be to map a API url such as:
http://api.example.org/resources/1
Directly to url such as:
http://frontend.example.org/resources/1
The issue I have with this, is that there's an implication that /resource/1 is taken from the frontend url and just added on to the api url. This is not something we're supposed to do, because it means we can't really evolve this api. If the server decides to link to a different server for example, the urls break.
Another option is that you generate uris such as:
http://frontend.example.org/http://api.example.org/resources/1
http://frontend.example.org/?uri=http://api.example.org/resources/1
I personally don't think this is too crazy. It does mean that the frontend needs to be able to load that uri and figure out what 'view' to load for the backend uri.
A third possibility is that you add another api that can:
Generate short strings that the frontend can use as unique ids (http://frontend.example.org/[short-string])
This api would return some document to the frontend that informs what view to load and what the (last known) API uri was.
None of these ideas sound super great to me. I want a better solution to this problem, but these are things I came up with as I was contemplating this.
Super curious if there's better ideas out there!
The current URL that the user is viewing, and the steps it took to get to the current place, are both application state (in the HATEOAS sense).
The user reloading example.com/resources/1/ is simply re-affirming the current application state, and the client does not need to do any API traversal to get back here.
Your client application should know the current URL, but that URL is saved on the client machine (in RAM, or disk cache, or a history file, etc.)
The starting point of the API is (well, can be) compiled-in to your client. Commpiled-in URLs are what couple the client to the server, not URLs that the user has visited during use of the client, including the current URL.
Your question, "For example, if the user requests a Resource with a particular ID", indicates that you have not grasped the decoupling that HATEOAS provides.
The user NEVER asks for a resource with such-and-such an ID. The user can click a link to get a query form, and then the server provides a form that generates requests to /collection/{id}. (In HTML, this is only possible for query strings, not path components, but other hypermedia formats don't have this limitation).
When the user submits the form with the ID number in the field, the client can build the request URL from the data supplied by the server+user.
I created a bucket for my root folder in the US Standard region but when I created my www. subdomain that could be redirected to the root folder I placed it in the Oregon region.
The redirect from the address bar is failing (I set it up using buckets>properties>redirect). AWS doesn't seem to allow this swapping between regions, so I deleted and tried to recreate the www. subdomain again, this time in the US Standard region, but it now gives the error, "A conflicting conditional operation is currently in progress against this resource. Please try again."
In short, is there a way to change the region, as AWS is apparently not allowing multiple buckets with the same name (even in separate regions)? I am planning to redirect from the domain name I registered online using Route 53 anyway, so does this issue matter (as I won't use the 'http://example.com.s3-website-us-east-1.amazonaws.com' or 'http://www.example.com.s3-website-us-east-1.amazonaws.com' because I will hopefully be using 'example.com' or 'www.example.com'.
Thank you all for the help; I hope this post is specific enough. Cheers from a first post.
AWS doesn't seem to allow this swapping between regions,
That's not correct. A bucket configured for redirection does not care where it's redirecting to -- it can redirect to any web site, and the destination doesn't have to be another bucket...so this is a misdiagnosis of the problem you were/are experiencing.
AWS is apparently not allowing multiple buckets with the same name (even in separate regions)?
Well... no:
“The bucket namespace is global - just like domain names”
— http://aws.amazon.com/articles/1109#02
Only one bucket of a given name can exist within S3 at any point in time. Because S3 is a massive distributed global system, it can take time (though it should typically only take a few minutes) before you can create the bucket again. That's your conflict -- the deletion hasn't globally propagated.
“After a bucket is deleted, the name becomes available to reuse, but the name might not be available for you to reuse for various reasons. For example, some other account could create a bucket with that name. Note, too, that it might take some time before the name can be reused.”
— http://docs.aws.amazon.com/AmazonS3/latest/dev/BucketRestrictions.html
Once you get it created, focus on fixing the redirect. If you haven't yet configured the DNS in Route 53, then that would be the reason the redirect didn't work -- it can't redirect to something that isn't working. S3 accomplishes this magic by sending a browser redirect -- which is why you can redirect anywhere -- it doesn't resolve the new bucket destination internally.
You should be able to redirect using Redirect all requests to another host name as long as you have Static Website enabled on the bucket where you are redirecting too.
No there's no way to change the region other than deleting the bucket in a region and recreating it in another region. Bucket names are unique across all of S3.
You can use Route 53 to create an alias for any bucket by adding a CNAME record that way www.yoursite.com maps to something like http://www.example.com.s3-website-us-east-1.amazonaws.com
Hope this helps.
For rest service, I allow for retrieval of nodes. Am I suppose to be able to get the nodes even if I am not logged in. I enabled session authentication but i am still able to get the list of current nodes by just going to the endpoint/node of my Drupal Webiste website.
Anyone with the 'View published content' permission should be able to retrieve a node.
A URL to retrieve a node would look something like this:
http://www.example.com/my_endpoint_path/node/123.json
The path my_endpoint/node refers to the Index resource, which returns a list of nodes.
Here's a complete listing of examples for the Services module: http://tylerfrankenstein.com/user/4/code/drupal-services-examples
Is it appropriate to perform actions with REST, other than simple create (POST), read (GET), update (PUT), and delete (DELETE)? I'm kind of new to the whole RESTful theology, so bear with me, but how should I accomplish the following:
I have a web service that needs to talk to another web service. Web service A needs to "reserve" an object on Web service B. This object has a timeout of validity, but can be deleted immediately if need be. It's essentially a glorified permissions system which requires web services to reserve a space on web service B before taking any actions.
My initial thought was to 1. enable authentication of some sort, 2. in the serverside response to a GET call, reserve the space and return the result, and 3. provide immediate "unreservation" of the object via a DELETE call. Is this still being RESTful?
Yes, it's OK to perform actions with rest. What matters is that these actions should be guided by the representations you exchange.
If you think about the way the web works (via a browser), you do this all the time: you get an HTML form that lets you choose a number of actions you can perform. Then, you submit the form (typically via POST) and the action is performed.
It's good to be able to use DELETE via a programmatic client (which is something that non-AJAX requests in browsers wouldn't support), but the overall approach of a RESTful system should be very similar to what you find for websites (i.e. the focus should be on the representations: the equivalent of web pages in your system).
GET shouldn't have side effects, so don't use GET to make the reservation itself, use something like POST instead.
No - unlikely to be restful
From your description ...
2. in the serverside response to a GET call, reserve the space and return the result
GETs should be idempotent. For this reason alone, your service is unlikely to be restful because the state of the system after the first GET is different.
You really need to consider that a Reservation is a resource and should be created with a POST to a reservations container which will return the URI of the new resource in the Location header of the HTTP response. This UrI can be used by Get to return the resource and updated with a PUT
Post should be used to extend an existing resource and Put for replacing the state of a resource. In your case, consider the Post to be updating a list of Reservations and returning the URI of the new resource (not just the I'd). Put can be used for changing the state associated with the resource identified by the UR
You're on the right track, but your reservation of the object should be with a PUT; you're PUTting a reservation on the object, i.e. changing the underlying object.
PUT is the right verb here, since you know what resource you're modifying, and it should be idempotent for multiple requests.