How do I keep a nonexistent work ID from breaking an API query? - azure-devops

I am querying the Azure DevOps API to return data for several work items at a time. The basic query is:
https://dev.azure.com/<organization>/_apis/wit/workitems/?ids=1234,2345,3456&api-version=6.0
But if one of those is not a valid work item ID, it returns something like this within the JSON response:
"message":"TF401232: Work item 3456 does not exist, or you do not have permissions to read it."
To me it seems like a better response would be the normal multi-ID JSON object with that message as one of many work item ID responses, instead of letting an invalid response break the entire query. Is there any way to do that? I haven't found any argument that seems to accomplish that, but I could easily have missed it. Thank you.

You can use the errorPolicy query flag in the api url. Set errorPolicy to Omit. See below:
https://dev.azure.com/<organization>/_apis/wit/workitems/?ids=1234,2345,3456&errorPolicy=Omit&api-version=6.0
When you useerrorPolicy=Omit query flag. The nonexistent work item id will not break the API call. It will be omitted in the response instead.
See here for more URI Parameters.

Related

How to properly access children by filtering parents in a single REST API call

I'm rewriting an API to be more RESTful, but I'm struggling with a design issue. I'll explain the situation first and then my question.
SITUATION:
I have two sets resources users and items. Each user has a list of item, so the resource path would like something like this:
api/v1/users/{userId}/items
Also each user has an isPrimary property, but only one user can be primary at a time. This means that if I want to get the primary user you'd do something like this:
api/v1/users?isPrimary=true
This should return a single "primary" user.
I have client of my API that wants to get the items of the primary user, but can't make two API calls (one to get the primary user and the second to get the items of the user, using the userId). Instead the client would like to make a single API call.
QUESTION:
How should I got about designing an API that fetches the items of a single user in only one API call when all the client has is the isPrimary query parameter for the user?
MY THOUGHTS:
I think I have a some options:
Option 1) api/v1/users?isPrimary=true will return the list of items along with the user data.
I don't like this one, because I have other API clients that call api/v1/users or api/v1/users?isPrimary=true to only get and parse through user data NOT item data. A user can have thousands of items, so returning those items every time would be taxing on both the client and the service.
Option 2) api/v1/users/items?isPrimary=true
I also don't like this because it's ugly and not really RESTful since there is not {userId} in the path and isPrimary isn't a property of items.
Option 3) api/v1/users?isPrimary=true&isShowingItems=true
This is like the first one, but I use another query parameter to flag whether or not to show the items belonging to the user in the response. The problem is that the query parameter is misleading because there is no isShowingItems property associated with a user.
Any help that you all could provide will be greatly appreciated. Thanks in advance.
There's no real standard solution for this, and all of your solutions are in my mind valid. So my answer will be a bit subjective.
Have you looked at HAL for your API format? HAL has a standard way to embed data from one resources into another (using _embedded) and it sounds like a pretty valid use-case for this.
The server can decide whether to embed the items based on a number of criteria, but one cheap solution might be to just add a query parameter like ?embed=items
Even if you don't use HAL, conceptually you could still copy this behavior similarly. Or maybe you only use _embedded. At least it's re-using an existing idea over building something new.
Aside from that practical solution, there is nothing in un-RESTful about exposing data at multiple endpoints. So if you created a resource like:
/v1/primary-user-with-items
Then this might be ugly and inconsistent with the rest of your API, but not inherently
'not RESTful' (sorry for the double negative).
You could include a List<User.Fieldset> parameter called fieldsets, and then include things if they are specified in fieldsets. This has the benefit that you can reuse the pattern by adding fieldsets onto any object in your API that has fields you might wish to include.
api/v1/users?isPrimary=true&fieldsets=items

How to filter REST API JSON result by passing params

I'm trying to consume JIRA 2 API and trying to get custom fields. I want to further filter by passing appropriate criteria in URI itself. Current query I'm using is something similar to this:
http://localhost:8522/jira522/rest/api/2/issue/createmeta?expand=projects.issuetypes.fields
The result I'm getting from above request is about 2000 lines.. How can I further filter to get only Custom_fields and also under custom fields I need to only the ones which are required?
I'm pretty new to REST API. Please guide me If anything is wrong... TIA. I spent a lot of time browsing but don't know what exactly I need to search for or where exactly I need to get started.
You can use another queryParam just like expand and add further filtering or pagination.
http://localhost:8522/jira522/rest/api/2/issue/createmeta?expand=projects.issuetypes.fields&limit=1000

Add subcategories in a filtered API Restful resource

I'll give an example as the title might sound a bit confusing.
How to build a resource path for something like that:
GET /courses/?language=english&active=true/units
I want to filter the courses (not using an id as usually) and then get the units of this result. How would you do that? I guess using question marks between the path is not allowed.
That would depend a little on your DB schema of what is a "course" and a "unit". The whole point on using the RESTful way is to always build requests and urls resource-specific.
But let's say that one course has X units on it. Here's what i would do to make a RESTful path to that request:
Due to the path problem of filtering courses AND using the /unit suffix, it can be done by adding another query parameter that specifies what fields the request is supposed to return. Something like this:
GET /courses?language=english&active=true&fields=units
That would filter the courses, and then return only the 'units' field on the response. As i said, depending on your DB and models, if the units are not stored inside the courses, it would be a bad practice to get them by requesting a /courses path. In that case, first request the courses that match the desired filter, and then make another request to the /units context sending i.e the courses ID's as query parameters.

Retrieve only specific properties with REST GET API

I need to define a REST API which is supposed to take the object's unique identifier and return back the content. The content is retrieved from the database and is of JSON type.
So, I have a REST URL like this -
GET /data/{typename}/{objectid}
This would return the entire object content.
However, the content of the object could be large in size and so caller may like to specify only some or few of the properties to be sent as a response.
The natural thought that comes to me is to add a BODY to the GET API where user could specify the list of property names on that object to be retrieved.
But on doing some further research, it appears that a GET API with BODY is not recommended.
The other option that I can think of is to pass the property names in query string -
GET /data/{typename}/{objectid}?property=prop1&property=prop2...
But the list could easily become large.
Any suggestion on how should my API look like? Do I have to use POST?
Technically, using POST will work but is not preferred. If you are reading, use GET. Facebook, for example, has a similar use case where the /me endpoint has many filters, and the call is GET.
The final URL would be,
/me?fields=id,name,about,age_range,devices,currency,education
You can try it yourself from here,
https://developers.facebook.com/tools/explorer/145634995501895/?method=GET&path=me%3Ffields%3Did%2Cname%2Cabout%2Cage_range%2Cdevices%2Ccurrency%2Ceducation&version=v2.8
I recommend reading more about GraphAPI https://developers.facebook.com/docs/graph-api/overview/ and GraphQL https://graphql.org/
I would recommend using POST, because GET has a length limit.
What is the maximum length of a URL in different browsers?
otherwise you could make your query string look like this (for array)
so close :)
GET /data/{typename}/{objectid}?property[]=prop1&property[]=prop2...

Best practice for file-based search in rest service

I'm helping build a similarity search service for files. One way to search for something is with a GET request, by giving a file's URL, but I also need to allow clients to send the file directly. I have to following options:
Make the client send a GET request with a Payload; it seems this is not recommended -- HTTP GET with request body
Use something else than GET (maybe a PUT?) for file-based search. The problem is none of the other HTTP methods seems to suit this purpose.
What option would suit best here? I'm not an expert in this field, and I can't figure out what's the right thing to do in this situation.
Here is the rule I have always followed with REST.
GET - only querying data and returning a data set.
POST - Creating data in the database
PUT - Modifying data
DELETE - Destroy data in the database.
If you are sending a payload for search params, you can do a GET and put those params (assuming they are name/value pairs) in the query string of the URI.
i.e. http://my.simsearch.com?param1=first&param2=second ...
If you are actually going to change the database then a POST or PUT is in order.
I hope this helps.
I ended up sending the payload with a GET request. Even though it's not really recommended, hopefully no libraries will complain about this.