How to update share point 2013 list item in rest service - rest

This is my Rest service to update list item
URL: https://site/_api/lists/getbytitle('Test')/items(49)
Header
X-RequestDigest: some unique id from contextinfo post service
Content-Type: application/json;odata=verbose
X-HTTP-Method: MERGE
IF-MATCH: 49
Body
{
"__metadata": {
"type": "SP.Data.TestListItem"
},
"Title": "Title all1",
"Option1": "Updated 2"
}
When I run this URL in post man I get an error
The request ETag value __metadata.etag does not match the object's ETag value
"8".
But If I change IF-MATCH value in header as *, it's updating properly. Why I am getting an error if use ETag?

You are using the ETag incorrectly. The ETag will correspond to the item's Version not the item's ID.
The best way to test this is to do a get request for the item and look at the metadata for the ETag property. You will see something similar to this
{
"__metadata": {
"id":"Web/Lists(guid'xxxxxxxx')/Items(1)",
"uri":"https://site.sharepoint.com/site/subsite/_api/Web/Lists(guid'xxxxxx')/Items(1)",
"etag":"\"12\""
}
}
Notice the formatting of the ETag.
I can't think of any good reason to use the IF-MATCH for a specific ETag in the case of updating the item. The request parameter for the ID should be more than sufficient. Checking versioning with ETags is needed when wanting to PUT, MERGE, or DELETE a specific version of an item.
Check this Working with lists and list items with REST for more information.

Related

Adding "Automated Test Type" value under Associated Automation within Test Case in Azure DevOps

Does anybody know how to set the "Automated Test Type" value for a Test Case in Azure DevOps? We have UI Tests and Unit Tests, and this would be a really helpful way to distinguish them when querying for test cases.
Note: I am not looking for the answer of how to associate automation, this is already done as per screen shot - it's specifically the highlighted field that I am enquiring about. Thanks.
As a workaround, you can edit test cases through a work item query:
Then update Test Type and save work items:
The result:
You can update any field value using the REST api methods if you want to. In this case you would need to know the work item ID that you are trying to update, the name of the field you want to update, and the value you want to be applied to that field.
I assume you know the ID of the work item you are trying to update. You can get the field name of the field by calling the GET request in the REST API as follows:
https://dev.azure.com/{{organization}}/{{project}}/_apis/wit/workitems/{{workItemID}}?$expand=Relations&api-version=5.0
using Postman or similar tool
This query will return all the fields of the specified work item and you can infer the field name from the return. The structure should look something like this
"fields": {
"System.AreaPath": "Test Strategy - Research\\Training",
"System.TeamProject": "Test Strategy - Research",
"System.IterationPath": "Test Strategy - Research",
"System.WorkItemType": "Test Case",
"System.State": "Design",
"System.Reason": "New",
for custom fields you should see a line that is something like
"[custom_name].[field_name]":"[value]"
You can update this value with a PATCH to the same REST endpoint but you need to create a data body with the desired field data. The sample post below was captured in Fiddler and will update the priority of a work item:
PATCH https://dev.azure.com/itineris/Test%20Strategy%20-
%20Research/_apis/wit/workitems/335392?api-version=6.0 HTTP/1.1
Host: dev.azure.com
Accept: application/json
Authorization: Basic
OnVhMmg3NWt4MnEyc2hkbW1lamZpdG5sMmlpN3NqZ3c1Y2tqdXVsNGdob3drb3h5MnZsYWE=
Content-Type: application/json-patch+json; charset=utf-8
Content-Length: 86
[{"op":"add","path":"/fields/Microsoft.VSTS.Common.Priority","from":null,"value":"1"}]

HTTP POST response Location header when creating multiple resources

The HTTP/1.1 standard states that if a POST operation results in the creation of a resource, then the response should include a Location header with the address of the new resource.
If a resource has been created on the origin server, the response
SHOULD be 201 (Created) and contain an entity which describes the
status of the request and refers to the new resource, and a Location
header (see section 14.30).
and in section 14.30,
For 201 (Created) responses, the Location is that of the new resource
which was created by the request.
Now suppose that my API allows batch creation of resources by POSTing an array to the collection resource URL. For example:
POST /books
[
{
"name": "The Colour of Magic",
"published": "1983"
},
{
"name": "The Light Fantastic",
"published": "1986"
}
]
Since two \book\{bookId} resources have been created, what should be the value of the Location header in this case?
The question Http post response after multiple new resource creation? is similar, but it asks about the response entity, not the headers (and is unanswered).
RFC 2616 is obsolete. Stop looking at it except for historical purposes.
The current spec, RFC 7231, says:
"If one or more resources has been created on the origin server as a result of successfully processing a POST request, the origin server SHOULD send a 201 (Created) response containing a Location header field that provides an identifier for the primary resource created (Section 7.1.2) and a representation that describes the status of the request while referring to the new resource(s)." -- http://greenbytes.de/tech/webdav/rfc7231.html#POST
And yes, that doesn't help a lot when there isn't a "primary" resource.
I know this answer is late to the party but I believe the best solution is to create a new "Batches" resource with a uuid identifier that would return the list of Book URLs that were added using a URL like this:
http://api.example.com/batches/{uuid}
e.g.
http://api.example.com/batches/2b9b251f71a4b2901d66e04725bc0c9cb5843c74
Then your POST or PUT can return the above URL on it's Location: {url} header and a 201 - Created status code.
If you then GET that URL that resource should respond with a representation that lists the URLs created in that batch, as well as any other info about the batch such as its uuid and the time/date it was created.
{
"uuid": "2b9b251f71a4b2901d66e04725bc0c9cb5843c74",
"datetime": "2005-08-15T15:52:01+00:00",
"books": [
"http://api.example.com/books/the-colour-of-magic",
"http://api.example.com/books/the-light-fantastic"
]
}
Those resources could then have a TTL of an hour or a month, whatever you choose. Or they could live forever if you want; whatever your use-case requires.
I think that you are in a particular use case for the header Location. In the case of bulk creation, the result of the processing is generally provided within the returned content itself. As a matter of fact, the processing can be completely or partially successful. I mean all elements were added or only a subset and the result shows to the end-user what actually happens.
So I think that the header Location isn't usable in such context. I see two options for the status code:
The status code is 201 if at least one element is created)
The status code is 200 to tell that the bulk request globally succeeds but the result of each operation is described in the response content.
You can however notice that a status code 202 exists if your resource handles the bulk creations in an asynchronous way. But in the context, you need then to pull a resource to get the status of the inserts.
Regarding the content of the response, you are free to choose. We could imagine something like that:
{
"took": 4,
"errors": true | false,
"items": [
{ "added": true,
"error": null
"id": "123"
},
{ "added": false,
"error": {
"code": "err12",
"description": "validation error (field type, ...)"
}
"id": null
}
]
}
ElasticSearch provides such bulk api with create but also update and delete support - see this link for more details: http://www.elastic.co/guide/en/elasticsearch/guide/current/bulk.html.
Here are similar questions that could give some hints:
How to Update a REST Resource Collection
REST API - Bulk Create or Update in single request
Hope it helps you,
Thierry

JAX-RS passing parameters to a PUT request

I've heard that in REST world, POST is recommended to create an entry, while PUT is recommended to update an entry.
First, I'd like a confirmation of this statement.
Then, using this assumptions, let's say I have a #POST method to create a user and a #PUT method to update a user (with a #QueryParam to pass the user ID).
What is the correct way to pass parameters to POST and PUT?
Is #FormParam appropriate for #PUT? Or should I pass a JSON in the body?
Should I pass parameters the same way for both #POST and #PUT or a different way?
Or should I use POST for both?
Edit: This question initially showed an example that did not work for me, but it was because my testing tool was doing it wrong. It works with POSTMAN now.
Yes, with REST, you typically use the following:
The method POST of the element list resource to add an element
The method PUT of the element resource to completely update an element
The method PATCH of the element resource to partially update an element
Since what you must send corresponds to the state of the resource, you have to provide it within the request body.
The two bodies (for adding and updating) is similar but there are some differences. For example, if you expect the RESTful service to autogenerate some fields, you don't have to provide corresponding ones.
Here are sample requests:
POST /contacts
{
"lastName": "my last name",
"firstName": "my first name",
}
(corresponding response status code: 201 - Created)
PUT /contacts/contactid
{
"lastName": "my last name",
"firstName": "my first name",
}
(corresponding response status code: 204 - No content)
You can notice that JSON isn't the only format you can use. XML, YAML, and so on could also be used.
I think that the following link could give you some hints:
Designing a Web API - https://templth.wordpress.com/2014/12/15/designing-a-web-api/
Hope it helps you,
Thierry

RESTful way to accept a choice

I have a simple api, that works like this:
A user creates a request ( POST /requests)
Another user retrieves all requests ( GET /requests)
Then adds an offer to a request ( POST /requests/123/offers)
Original user can now see all the offers being made for the request (GET /requests/123/offers)
What i want to do, is allow the inital user to accept an request, but I can't figure out the best way to do it RESTfuly.
Should I do it with the PATCH verb? Like PATCH /requests/123 and require that the patch body contain a valid offer id?
Accepting an offer five times should have the same effect as accepting it once. It is idempotent. So it should be a PUT.
You might want to consider choosing a different name for your "requests." When I do GET /requests/123, I request a response that is a request? This could be a little confusing for clients.
Additionally, try to avoid nesting your resource identifiers. That can create problems for you later. An offer doesn't really have to be "underneath" the corresponding request. What happens when you later want to have offers corresponding to multiple requests?
A good rule of thumb is, if you would consider "Gizmo" an entity in an entity-relationship model, it should be a root-level URI, like in GET /gizmos/17, not GET /widgets/54/gizmos/17. A common mistake is to say "Every Gizmo has exactly one related Widget, so I should nest Gizmo URIs as extensions of Widget URIs."
Below I have a suggestion for how the operations would look. You may want to replace some of the ID references with URIs instead, but that's up to you.
POST /requests ---> 201 Created
Location: /requests/123
GET /requests ---> 200 OK
[
{
"requestId": 123,
"offersUri": "/offers?requestId=123",
...
},
...
]
POST /offers ---> 201 Created
{ Location: /offers/456
"requestId": 123,
"amount": 300,
...
}
GET /offers?requestId=123 ---> 200 OK
[
{
"requestId": 123,
"amount": 300,
...
}
]
PUT /offers/456/approval ---> 204 No Content
PUT /offers/456/approval ---> 204 No Content
PUT /offers/456/approval ---> 204 No Content
Depends on the nature of the Acceptance.
If Acceptance is a simple attribute of an offer, I would POST the Offer with the Acceptance set to True.
If the Acceptance is more complex and therefore a resource in its own right, I would PUT an Acceptance into the offer (PUT /requests/123/offers/acceptance).
If there exists such a thing as a rejection, or a request for offer clarification, I might consider the relevant resource to be a Response, not an Acceptance, and PUT that (put /requests/123/offers/response).

REST: Best practice for partial update of subset of collection

I am trying to understand a little bit more about the REST ways :). Let's say I have a collection of ProductTypes that one can retrive via url GET /productTypes and let's say that we can but don't have to apply any filter. So this fetches 500 records.
Now if I want to do full update of the resource I could use PUT or POST at /productTypes/123. So far so good.
If I am creating a new resource and I know the id ahead of time, I would use PUT at /productTypes/123 and return 201 otherwise for update PUT with 200.
If I do partial update of the resource I would do PUT or POST at /productTypes/123/displayOrder and return 303 indicating that some other resource has been modified.
But what if I do 1 POST sending in basically a list of Key-Value pairs of product Id and display order, and I modify 5 out of 500 records. How do I indicate now that these 5 records have changed?
What happens with GET at /productTypes now after this partial update. I read somewhere that instead of returning multiple records with this get, I should return the list links to the resources, and then fetch them one by one, as that would allow for insane caching. But still how do I indicate that 5 records have changed? Do I need to do 5 separate posts with 303, or is there different mechanism. Hope this makes sense.
I don't see anything in the spec that specifically bars you from using multiple Content-Location headers. I tested it out and Chrome's totally OK with it. It won't automatically redirect for you, but you don't want that anyway with multiple resources involved.
HTTP/1.1 303 See Other
Content-Location: /productTypes/123/displayOrder
Content-Location: /productTypes/456/displayOrder
Content-Location: /productTypes/789/displayOrder
Content-Location: /productTypes/012/displayOrder
Content-Location: /productTypes/345/displayOrder
I'd do this:
PATCH /productTypes HTTP/1.1
Content-Type: application/json
{"item":[
{"id":"1","displayOrder":"4"},
{"id":"2","displayOrder":"2"},
{"id":"3","displayOrder":"1"},
{"id":"4","displayOrder":"3"},
{"id":"5","displayOrder":"5"}
]}
HTTP/1.1 200 OK
Content-Type: application/hal+json
{
"_links": { "self": {"href": "/productTypes" } }
"_embedded": {
"item": [{
"_links": { "self": { "href": "/productTypes/1" } },
"displayOrder": "4"
},
/* 4 more entries */
]
}
}