I have a doubt. When is a GET request sent. I mean, I have seen a lot of people using if request.method == 'GET', when they render the form for the first time, but when the form is submitted, they do a `POST' request.
While they explicitly mention when defining the form in html that the method will be 'POST', they don't do the same for 'GET' request which is made when an empty form is requested.
How does django know it's a GET request?
And, why is it done so?
Thanks,
I'm not an expert but I think Django "knows" this because like all things on the Internet it uses the HTTP protocol. There are several HTTP methods. If not specified the default method will always be GET
GET
A GET is usually used to retrieve information. Typically a GET function has no side-effects (this means that data in the database is not changed, that no files in the filesystem are modified, etc.).
Strictly speaking this is not always true, since some webservers log requests (themselves) and thus add an entry to the database that a specific user visited a specific page at a specific timestamp, etc.
A typical GET request is idempotent. This means that there is no difference between doing a query one time, or multiple times (two times, three times, five times, thousand times).
GET queries are therefore typically used to provide static content, as well as pages that contain data about one or more entries, search queries, etc.
POST
POST on the other hand typically ships with data (in the POST parameters), and usually the idea is that something is done with this data that creates a change in the persistent structures of the webserver. For example creating a new entry in some table, or updating the table with the values that are provided. Since these operations are not always idempotent, it can be dangerous if the user refreshes the page in the browser (since that could for example create two orders, instead of the single order the user actually wanted to create).
Therefore in Django a POST request will typically result in some changes to the database, and a redirect as result. This means that the user will typically obtain a new address, and perform a GET request on that page (and that GET is idempotent, hence it will not construct a new order).
PUT, PATCH and DELETE
Besides the popular GET and POST, there are other typical requests a client can make to a webserver. For example PUT, PATCH and DELETE.
PUT
PUT is the twin of a POST request. The main difference is that the URI it hits, specifies what entry to construct or update. PUT is usually an idempotent operation.
This means that if we would for example perform a POST server.com/blog/create to create a blog, PUT will typically look like PUT server.com/blog/123/. So we specify the id in advance. In case the object does not yet exists, a webserver will typically construct one. In case the entity already exists, a new entity will typically be constructed for that URI. So performing the same PUT operation twice, should have no effect.
Note that in case of a PUT request, typically one should specify all fields. The fields that are not specified will typically be filled in with default values (in case such values exist). We thus do not really "update" the entity: we destroy the old entity and create a new one in case that entity already exists.
PATCH
PATCH is a variant of PUT that updates the entity, instead of creating a new one. The fields that are thus missing in a PATCH request, typically remain the same as the values in the "old" entity so to speak.
DELETE
Like the name already suggests, if we perform a DELETE server.com/blog/123/ request, then we will typically remove the corresponding element.
Some servers do not immediately remove the corresponding element. You can see it as scheduling the object for deletion, so sometimes the object is later removed. The DELETE request, thus typically means that you signal the server to eventually remove the entity.
Actually Django is based on HTTP responses-requests. HTTP is fully textuall. So Django parses each request and finds in its header information about what kind of request is it. I may be mistaken in details, but as I understand when server receives request - Django creates it's object request, which contains all the data from HTTP. And then you decide if you need a specific action on GET or POST and you check the type of request with request.method.
P.S. And yes, by default each request is GET.
Related
I read a lot about each and every function of those mentioned in the title,
But I always have doubt that what is the primary use of all individual functions. Can someone explain to me in detail? Thank you.
What is the use of all GET, PUT, DELETE when anything can be done by POST
This is a pretty important question.
Note that, historically, SOAP essentially did everything by POST; effectively reducing HTTP from an application protocol to a transport protocol.
The big advantage of GET/PUT/DELETE is that the additional semantics that they promise (meaning, the semantics that are part of the uniform interface agreed to by all resources) allow us to build general purpose components that can do interesting things with the meta data alone, without needing to understand anything specific about the body of the message.
The most important of these is GET, which promises that the action of the request is safe. What this means is that, for any resource in the world, we can just try a GET request to "see what happens".
In other words, because GET is safe, we can have web crawlers, and automated document indexing, and eventually Google.
(Another example - today, I can send you a bare URI, like https://www.google.com and it "just works" because GET is understood uniformly, and does not require that we share any further details about a payload or metadata.)
Similarly, PUT and DELETE have additional semantic constraints that allow general purpose components to do interesting things like automatically retry lost requests when the network is unreliable.
POST, however, is effectively unconstrained, and this greatly restricts the actions of general purpose components.
That doesn't mean that POST is the wrong choice; if the semantics of a request aren't worth standardizing, then POST is fine.
In API perspective,
GET - It is to retrieve record/data from a source. API would need no data from client/UI to retrieve all records , or would need query param / path param to filter records based on what is required - either record with a particular ID or other properties.
POST - it is to store a new record at a source . API would get that record from client/UI through request body and store it.
PUT - it is to update an existing record at a source . API would receive updated record along with Id and update it with existing record whose id match with one passed from UI.
DELETE - it is to delete a record present in source. UI would send nothing to delete whole all records at source or send id to remove a particular record.
Source refers to any database.
A simple REST API:
GET: items/{id} - Returns a description of the item with the given id
PUT: items/{id} - Updates or Creates the item with the given id
DELETE: items/{id} - Deletes the item with the given id
Now the API-extension in question:
GET: items?filter - Returns all item ids matching the filter
PUT: items - Updates or creates a set of items as described by the JSON payload
[[DELETE: items - deletes a list of items described by JSON payload]] <- Not Correct
I am now being interested in the DELETE and PUT operation recycling functionality that can be easily accessed by PUT/DELETE items/{id}.
Question: Is it common to provide an API like this?
Alternative: In the age of Single Connection Multiple Requests issuing multiple requests is cheap and would work more atomic since a change either succeeds or fails but in the age of NOSQL database a change in the list might already have happend even if the request processing dies with internal server or whatever due to whatever reason.
[UPDATE]
After considering White House Web Standards and Wikipedia: REST Examples the following Example API is now purposed:
A simple REST API:
GET: items/{id} - Returns a description of the item with the given id
PUT: items/{id} - Updates or Creates the item with the given id
DELETE: items/{id} - Deletes the item with the given id
Top-resource API:
GET: items?filter - Returns all item ids matching the filter
POST: items - Updates or creates a set of items as described by the JSON payload
PUT and DELETE on /items is not supported and forbidden.
Using POST seems to do the trick as being the one to create new items in an enclosing resource while not replacing but appending.
HTTP Semantics POST Reads:
Extending a database through an append operation
Where the PUT methods would require to replace the complete collection in order to return an equivalent representation as quoted by HTTP Semantics PUT:
A successful PUT of a given representation would suggest that a subsequent GET on that same target resource will result in an equivalent representation being returned in a 200 (OK) response.
[UPDATE2]
An alternative that seems even more consistent for the update aspect of multiple objects seems to be the PATCH method. The difference between PUT and PATCH is described in the Draft RFC 5789 as being:
The difference between the PUT and PATCH requests is reflected in the way the server processes the enclosed entity to modify the resource identified by the Request-URI. In a PUT request, the enclosed entity is considered to be a modified version of the resource stored on the origin server, and the client is requesting that the stored version be replaced. With PATCH, however, the enclosed entity contains a set of instructions describing how a resource currently residing on the origin server should be modified to produce a new version. The PATCH method affects the resource identified by the Request-URI, and it also MAY have side effects on other resources; i.e., new resources may be created, or existing ones modified, by the application of a PATCH.
So compared to POST, PATCH may be also a better idea since PATCH allows an UPDATE where as POST only allows appending something meaning adding without the chance of modification.
So POST seems to be wrong here and we need to change our proposed API to:
A simple REST API:
GET: items/{id} - Returns a description of the item with the given id
PUT: items/{id} - Updates or Creates the item with the given id
DELETE: items/{id} - Deletes the item with the given id
Top-resource API:
GET: items?filter - Returns all item ids matching the filter
POST: items - Creates one or more items as described by the JSON payload
PATCH: items - Creates or Updates one or more items as described by the JSON payload
You could PATCH the collection, e.g.
PATCH /items
[ { id: 1, name: 'foo' }, { id: 2, name: 'bar' } ]
Technically PATCH would identify the record in the URL (ie PATCH /items/1 and not in the request body, but this seems like a good pragmatic solution.
To support deleting, creating, and updating in a single call, that's not really supported by standard REST conventions. One possibility is a special "batch" service that lets you assemble calls together:
POST /batch
[
{ method: 'POST', path: '/items', body: { title: 'foo' } },
{ method: 'DELETE', path: '/items/bar' }
]
which returns a response with status codes for each embedded requests:
[ 200, 403 ]
Not really standard, but I've done it and it works.
Updating Multiple Resources With One Request - Is it standard or to be avoided?
Well, sometimes you simply need to perform atomic batch operations or other resource-related operations that just do not fit the typical scheme of a simple REST API, but if you need it, you cannot avoid it.
Is it standard?
There is no universally accepted REST API standard so this question is hard to answer. But by looking at some commonly quoted api design guidelines, such as jsonapi.org, restfulapi.net, microsoft api design guide or IBM's REST API Conventions, which all do not mention batch operations, you can infer that such operations are not commonly understood as being a standard feature of REST APIs.
That said, an exception is the google api design guide which mentions the creation of "custom" methods that can be associated via a resource by using a colon, e.g. https://service.name/v1/some/resource/name:customVerb, it also explicitly mentions batch operations as use case:
A custom method can be associated with a resource, a collection, or a service. It may take an arbitrary request and return an arbitrary response, and also supports streaming request and response. [...] Custom methods should use HTTP POST verb since it has the most flexible semantics [...] For performance critical methods, it may be useful to provide custom batch methods to reduce per-request overhead.
So in the example case you provided you do the following according to google's api guide:
POST /api/items:batchUpdate
Also, some public APIs decided to offer a central /batch endpoint, e.g. google's gmail API.
Moreover, as mentioned at restfulapi.net, there is also the concept of a resource "store", in which you store and retrieve whole lists of items at once via PUT – however, this concept does not count for server-managed resource collections:
A store is a client-managed resource repository. A store resource lets an API client put resources in, get them back out, and decide when to delete them. A store never generates new URIs. Instead, each stored resource has a URI that was chosen by a client when it was initially put into the store.
Having answered your original questions, here is another approach to your problem that has not been mentioned yet. Please note that this approach is a bit unconventional and does not look as pretty as the typical REST API endpoint naming scheme. I am personally not following this approach but I still felt it should be given a thought :)
The idea is that you could make a distinction between CRUD operations on a resource and other resource-related operations (e.g. batch operations) via your endpoint path naming scheme.
For example consider a RESTful API that allows you to perform CRUD operations on a "company"-resource and you also want to perform some "company"-related operations that do not fit in the resource-oriented CRUD-scheme typically associated with restful api's – such as the batch operations you mentioned.
Now instead of exposing your resources directly below /api/companies (e.g. /api/companies/22) you could distinguish between:
/api/companies/items – i.e. a collection of company resources
/api/companies/ops – i.e. operations related to company resources
For items the usual RESTful api http-methods and resource-url naming-schemes apply (e.g. as discussed here or here)
POST /api/companies/items
GET /api/companies/items
GET /api/companies/items/{id}
DELETE /api/companies/items/{id}
PUT /api/companies/items/{id}
Now for company-related operations you could use the /api/companies/ops/ route-prefix and call operations via POST.
POST /api/companies/ops/batch-update
POST /api/companies/ops/batch-delete
POST /api/companies/ops/garbage-collect-old-companies
POST /api/companies/ops/increase-some-timestamps-just-for-fun
POST /api/companies/ops/perform-some-other-action-on-companies-collection
Since POST requests do not have to result in the creation of a resource, POST is the right method to use here:
The action performed by the POST method might not result in a resource that can be identified by a URI.
https://www.rfc-editor.org/rfc/rfc2616#section-9.5
As far as I understand the REST concept it covers an update of multiple resources with one request. Actually the trick here is to assume a container around those multiple resources and take it as one single resource. E.g. you could just assume that list of IDs identifies a resource that contains several other resources.
In those examples in Wikipedia they also talk about resources in Plural.
I know differences and advantages of each command, my question is could I replace POST requests with GET everywhere? And which these commands calls by default while sending request from html form?
could I replace POST requests with GET everywhere
No (and it would be a terrible idea to try).
Things that a form can do with POST that you can't do with GET include:
Sending lots of data
Sending files
There are other things that would simply be stupid to do with GET.
From http://www.w3.org/TR/html5/forms.html#attr-fs-method :
The method and formmethod content attributes are enumerated attributes
with the following keywords and states:
The keyword get, mapping to the state GET, indicating the HTTP GET
method. The keyword post, mapping to the state POST, indicating the
HTTP POST method. The invalid value default for these attributes is
the GET state. (There is no missing value default.)
When using GET to transfer data from the client to the server, the data is added to the URL, there is not BODY of the request. There is usually a limit on how long a URL can be, in the old days this was 1024 characters but that really depends on the server software and server middleware and even the browser.
This means if you want to transfer loads or data or upload a file to the server, you can not do it with GET.
I've looked at many SO answers about REST, but the concept is still not clear.
At least, it seemed to me naming(the URL) properly is central to what REST is.
How do I make my address scheme below restful?
(I have list of images, but for each request I present different subset of them)
image_list/recent (all image sorted in descending)
image_list/recent/front/ (to request newer images than a client has. client will provide the latest image id he has)
image_list/popular (sorted in popularity)
image_list/following/ (list of images of users that a client follows)
image_list/user_like/ (list of images a client likes)
how about when you have many operations that you can perform on a resource?
image/upload/
image/delete/
image/like/
image/dislike/
image/hide/
EDIT
This is the solution after looking at answers.
(But I still have doubts and did indicate so)
First set
images/?mode=recent
images/?mode=recent_front
images/?mode=popular
images/?mode=following&user_id=3
images/?mode=like&user_id=3
Isn't it a convention to use images/ for all images even though the all images set keeps changing?
Why can't I just use images/recent then?
Second set
images/ POST (to create)
images/ DELETE
(to delete, ok but I have not seen anyone using `DELETE`. Does anyone use it?)
images/3/like POST (OK there's a `like` DB entity)
images/3/dislike POST (umm but there's no dislike DB entity)
images/3/hide .. (there's no hide entity, it's a merely a field on image)
As I'm sure you know, REST is much more than a naming scheme for URLs.
What's important with your URI naming scheme is that the URI uniquely identifies a particular resource/entity. Quoting directly from the Wiki page:
An important concept in REST is the existence of resources (sources of
specific information), each of which is referenced with a global
identifier (e.g., a URI in HTTP).
In your case, you want your URIs to structured so that they can uniquely identify an image or the collection of all images as a whole. There is more than one way to do this. Some people prefer query strings and others (including myself) prefer including identifiers as part of the URI folder structure. REST doesn't dictate one or the other.
Think about what you need to identify an image--it could be a filename, but if your application is database driven, it's more likely you'd be using an index ID number. You could setup your URI as such:
http://YOURDOMAIN.TLD/API/IMAGE/232423
Where 232423 uniquely identifies the image.
Now on to your second question:
how about when you have many operations that you can perform on a resource?
With REST APIs over HTTP, the action is typically specified by the HTTP method you utilize. GET for retrieving data, POST for updating/inserting data and DELETE for deleting data. It's not common practice to have the URI itself specify the action--as you've done above. Please note, that I'm talking about what's common practice--the principles of REST don't dictate what HTTP methods should be used or the URI naming structure.
Taking your example of likes on an image, you should treat the likes on the page as a resource--a unique entity. There are different actions that you want to do with this entity such as: 1. look up the number of likes on an image, 2. add a new like to the total.
For your REST method to like an image, you could set it up as a POST to a URI like this:
http://YOURDOMAIN.TLD/API/IMAGE/232423/LIKE
Where 232423 is an identifier for the image and LIKE refers to the likes on that particular image.
If you wanted to retrieve the number of likes on the image, use the same URI, but switch the HTTP method to GET.
Is there common design pattern for dispatching deleted objects to the requestor (client of the API)?
Challenges we are having:
When object is deleted on the API completely, client will not know
that object is gone and will keep it locally (as API only shows objects changed after the certain date)
If we enable object's property to show that is deleted (ex. "deleted = TRUE") then
eventually number of objects in the API grows and slows down the transfer rate.
Another option we looking into is to have separate Endpoints on the API to show list of deleted objects only (is this the pattern that anyone uses?).
I'm looking for most "RESTful way" to delete local objects.
The way I handle it is a variation on your #1: each item has a last updated field in the database, and if something is deleted, I make an entry in another table of deleted items, and it's updated value is when it was deleted.
The client makes a request asking for "changes since X" which is their own locally stored last updated value...it returns new data, and an array of deleted items. Then on the client I purge those values
Stale data is always a problem with client/server applications. If clients loads some data, then some object is deleted on the server, and then client sends a DELETE request, the RESTFul thing to do would be to return a 404, which indicated "not found". If the client knows that if it sends a DELETE, and gets a 404, the resource was deleting from underneath...
What if you think of your resource not as a list, but rather as a changeset?
Eg. changesets what you have in git or SVN.
This way, there's always a "head" version, and the client always has some version, and the resource is the change between client's last and head.
That way you can apply whatever you've learned by examining/using version control systems.
If you need anything more complex, the science behind is called Operational Transformation (OT) - http://en.wikipedia.org/wiki/Operational_transformation