Azure DevOps Webhooks (Service Hooks) Missing Fields like Description or Repro Steps - azure-devops

I am working on ASP.NET Core 5 project, which will use a subscription to my organization's Azure DevOps Service Hooks (Webhooks). I will analyze event payload's data (and metadata).
I checked what event payloads contains from here:
https://learn.microsoft.com/en-us/azure/devops/service-hooks/events?view=azure-devops#workitem.updated
And also downloaded this NuGet package: https://www.nuget.org/packages/Microsoft.AspNet.WebHooks.Receivers.vsts
But there is a problem. I cannot find (in the docs and also in the NuGet package) Work Item's "Description" field or Bug's "Repro Steps" fields. These two fields are most important fields from payload for my project.
Are these fields hidden somewhere? Or is possible to include these fields in payload?

After querying Work Item Types Field - List rest api which used to get a list of fields for a work item type with detailed references.
{
"alwaysRequired": false,
"defaultValue": null,
"allowedValues": [],
"dependentFields": [],
"referenceName": "System.Description",
"name": "Description",
"url": "https://dev.azure.com/fabrikam/_apis/wit/fields/System.Description"
},
The referenceName of Description field should be System.Description.
As you have pointed, seems this is not include in webhook event payload.
You may have to use work item Rest API to query corresponding info.

Related

Update Stock_level in OCAPI

How I can update the inventory (stock_level) using (business manager API).
I use the business manager API to retrieve products. I am able to retrieve the products but I am not sure how I can set its stock (stock_level).
I have a special requirement where product quantity cannot exceed 1, so for that I need to set it in an inventory so that I can test it.
I have tried to see if I can set inventory level using product but that doesn't seem possible.
When I try to get inventory following is the error
{
"_v": "18.8",
"fault": {
"arguments": {
"method": "GET",
"path": "/data/v18_8/inventory_lists/*"
},
"type": "ClientAccessForbiddenException",
"message": "Access to resource 'GET /data/v18_8/inventory_lists/*' is not allowed for the current client."
}
}
There is actually a DATA API endpoint that can be used to update inventory. It is called the ProductInventoryRecords resource.
You can update a product inventory record with a PATCH eg:
PATCH /inventory_lists/{inventory_list_id}/product_inventory_records/{product_id}
With a ProductInventoryRecordAllocation payload as such:
{
"_resource_state" : "847f9c3c5867f641470b3046aeec31f07757991b792d722e10079926f7a289fb",
"allocation": {
"amount": 2000,
"reset_date": "2016-03-31T14:05:40.872Z"
}
}
See more about this document type here.
Please note that the best practice is to pass the _resource_state key to ensure that the record is properly updated. OCAPI checks to see if this value is the same as the current state of the record if that attribute provided.
So systems should first check the record to get the _resource_state by performing a GET on the same resource.
Edit Note that you'll need an authorization token that grants you access to the API in order to make this kind of call.
your question is not crystal clear but I will try to answer. Commerce Cloud has three distinct (OCAPI) APIs:
Shop API (provides similar access as a customer on the site)
Data API (provides similar access as a merchant using business manager)
Meta API (describes the API from a functional perspective)
To get availability of a product in the inventory use below call: {{shop_url}}/products/701644676568M/availability and look at ATS in the response.
To set the stocklevel go into to business manager or use business manager import utility. There is no out-of-the-box API to update the stocklevel.

REST: How to update a row and create zero or more of other resource on same request?

I'll try to make this as simple as possible, it may be sort of dumb question.
I'm rewriting an 7 years old web application (help desk software). It is required to make it a REST API to be consumed by different clients web browser and mobile app. Also required to keep the business logic as close as possible to the original which for now have been working well.
The current struggle about REST:
What I need is to update the a resource lets say /tickets/47321
If the status_id of the this resource is changed a record of this change need to be saved, both in the same DB transaction because it need to be all-or-nothing. this is how the original application worked and we would like to keep this behavior.
So question is:
Can I PUT to tickets/47321 the whole resource or partial state representation to update the resource residing in server and create the new record of the history change (if status_id is different) and return them both back to client as JSON:
{
ticket: {}, // new ticket state
history: {} // the new created record of history change
}
This way the client can update the ticket and add the history to a list of history changes if there is any being return?
Technically, yes, you can do this. However, it might not be as straightforward as simply returning 2 objects, side by side; looking at the Richardson Maturity Model (Level 1), one would expect to receive the same type of resource after
calling (PUT) an api endpoint.
That being said, you could either embed the additional resource (append a history change to a ticket, following the Hypertext Application Language (HAL) proposed draft specification), or better yet (if you're aiming towards REST level 3), provide a link relationship, in conformity with the "Target IRI" defined in Web Linking specification (RFC 5988) from the ticket:
/api:history?ticketId=47321 would return all the history records belonging to that ticket, paged and sorted by created date, for example (and you can just select the latest)
/api:history?id=123 you would do some work on the server to ensure this points straight to the latest history record (related to that ticket id)
Regarding the partial update, looking at the RFC 6902 (which defines the Patch standard), from the client's perspective the API could be called like
PATCH /ticket/47321
[
{ "op": "replace", "path": "/author", "value": "David"},
{ "op": "replace", "path": "/statusId", "value": "1"}
]
More examples can be found here.

Updating composite entities in a RESTful resource

I have an entity with several attributes, say «project». Apart from simple attributes, the project may have a list of «statuses» of which the last one is the current one. I have a web form to create/edit a project. All attributes of this project can be changed in this form, and also users can add a new status for the project (but they can’t change or delete old statuses).
Project statuses are purely composite entities, they don’t have any distinctive meaning or identity outside of the project scope, and they are not to be addressed directly, so they obviously don’t deserve a special root REST resource.
According to REST architecture, I created a resource called /projects. POST is used to create a new project, and PUT is used to change an existing project.
However, I don’t want the client to PUT the project together with all its historical statuses, firstly because this collection is too heavy, and secondly because the business logic allows only for adding statuses, not changing or deleting them, so PUTting the project together with all of its statuses doesn’t make any sense anyway.
PUTting a project with only a new status is also not an option, because it violates the idempotency of PUT.
I also don’t like the idea of POSTing a status in a second HTTP-request, say /project/{id}/status, because that would break the atomicity of the update operation from the user’s standpoint. If this second request gets lost on the wire, then the project will appear inconsistent to the user who edited it (the attributes changed, but the status stayed the same). Creating RESTful "transactions" seems like overkill (and also error prone) for this simple task of updating a seemingly monolithic entity.
This kind of problem is quite ubiquitous in my work, and may be generalized as such: what is the RESTfully correct and atomic way of updating a complex composite entity for which only partial update is allowed by the business logic?
I think that if you want to do partial updates (it's actually your case), you should use the method PATCH. This allows to update either the project without dependencies (statuses) or the dependency(ies) without the project hints.
You can notice that there is a format to describe the operations to do within a method PATCH. It's called JSON Patch (see https://www.rfc-editor.org/rfc/rfc6902). This format describes what you want to do within your request: add an element, update it, remove it, ...
I think that you could have something like that if you want (for example) to update the name of a specific project, remove a status (it's also a sample since I read that you want to forbid this!) and add a new one in one atomic request:
PATCH /projects/1
[
{
"op": "replace",
"path": "/name",
"value": "the new name of the project"
},
{
"op": "remove",
"path": "/statuses/1"
},
{
"op": "add",
"path": "/statuses/",
"value": {
"name": "my status",
(...)
}
}
]
Notice that you can put what you want in the attribute name to identify the related element in the resource state. So /statuses/1 can be the second element in the array, the status with id of value 1 or something else.
The server-side processing for the request can be atomic.
I wrote a blog post about bulk updates: https://templth.wordpress.com/2015/05/14/implementing-bulk-updates-within-restful-services/. I think that the section "Implementing bulk updates" could correspond to what you look for.
Hope it helps you,
Thierry
Do you need HTTP PATCH? It is the verb to express delta updates to a resource.
https://www.rfc-editor.org/rfc/rfc5789

Deploying standard picklists via Metadata API

Have some trouble deploying leadSource and Industry picklists via Metadata API. Had to comment out both of them from the build. It may have something to do with these picklists being shared by multiple objects, I don't know. We are using Jenkins for the deployment. Here is a sample deployment error:
Error: objects/Lead.object(1150,13):An unexpected error occurred. Please include this ErrorId if you contact support: 1967816892-11483 (1554758315)
OK, we figured it out by trial and error, didn't see it documented anywhere.
There are some standard picklists that are shared by multiple objects: "Lead Source", "Account Source", and "Industry".
For example, "Lead Source" field is on Contact, CampaignMember, Lead, Opportunity, and Account. Although on Account it's named differently ("Account Source"), the picklist values are shared by all of these objects. To deploy this picklist, we need to make sure that we only list it on one of these objects, and comment it out from the others, otherwise we get a build error.
Currently our build is set up as follows:
1) "Lead Source" field is deployed via "Account Source" field on the Account object, from where the picklist values are copied by Salesforce automatically to four other objects.
2) Industry field is deployed via Account object. It is commented out on the Lead object. From Account, SF automatically makes these picklist values available on the Lead.

Backbone.js & REST API resources relationship & interraction

I have a small REST API that is being consumed by a single page web application powered by Backbone.js
There are two resource types that the API provides, and therefore, the Backbone app uses. These are articles and comments. These two resources have different endpoints and there is a link from each of the articles to the location of all the comments for that item.
The problem that I'm facing is that, on the article list in my web app I would like to be able to display the number of comments for each article. Given that that would only be possible if I also get the comments list, on the current setup, would require me to make one API request to get the the initial article list and another one for each of the articles to be able to count the number of comments. That becomes a problem if, for instance, there are 100 articles, and therefore 101 HTTP requests would be necessary to populate one single view.
The solutions I can think of right now are:
1. to include the comments data in the initial articles request like so
{
{
"id": 1,
"name": "Article 1",
...
"comments": {
{
"id": 1,
"text": "some comment"
},
{
"id": 2,
"text": "some comment"
},
...
}
},
}
The question in this case is: How is it possible to parse the "comments" as a separate comments collection and not include it into the article model?
2. to include some metadata inside the articles response like so:
{
{
"id": 1,
"name": "Article 1",
...
"comments": 13
},
}
Option that raises the question: how should I handle the parse of the model so that, on one hand the meta information is available, and on the other hand, the "comments" attribute is not one Backbone would try to perform updates on?
I feel there might be another solution, compliant with the REST philosophy, for this that I'm missing, so if you have any other suggestion please let me know.
I think your best bet is to go with your second option, include the number of comments for each article inside your article model.
Option that raises the question: how should I handle the parse of the model so that, on one hand the meta information is available, and on the other hand, the "comments" attribute is not one Backbone would try to perform updates on?
Not sure what your concern is here. Why would you be worried about the comments attribute getting updated?
I can't think of any other "RESTy" way of achieving your desired result.
I would suggest using alternative 2 and have the server return
a subset of the article attributes that are deemed useful for
applications when dealing with the article collection resource
(perhaps reachable at /articles).
The full article member resource with all its comments (whether
they are stored in separate tables in the backend) would be
available at /articles/:id).
From a Backbone.js point of view you probably want to put the
collection resource in a, say, ArticleCollection which will
convert each member (currently with a subset of the attributes)
to Article models.
When the user selects to view an article in full you pull it
out from the ArticleCollection and invoke fetch to populate
it in full.
Regarding what to do with extra/virtual attributes that are included
in the collection resource (/articles) like the comment count and
possibly other usefult aggregations, I see a few alternatives:
In Article#initialize you can pull those out from the attributes
and store them as meta-data on the article. This way the built-in
Backbone.Model#toJSON will not see them.
Keep them in the attributes section of each model and override
Backbone.Model#toJSON to exlcude them when "serializing" an Article.
In atlernative 1, an Article#commentCount() helper could return
this._commentCount || this.get('comments').length to make it work
on both partially and fully loaded articles.
For a fully loaded Article you would probably want to convert the
nested comments array into a full-blown CommentCollection anyway
and store that in this._comments so I don't think it is that unusual
to have your models store additional stuff directly on the model instance,
outside of its attributes hash.