I am refreshing tabular models in Azure using a logic app and the REST API. This is detailed here;
https://learn.microsoft.com/en-us/azure/analysis-services/analysis-services-async-refresh
The refresh starts with the POST, which is fine. however I want to poll the SSAS instance to know when the processing is complete. The documentation states that;
"The Location header in the response includes the refresh ID. The client application can disconnect and check the status later if required because it is asynchronous."
However the header response is like this;
{
"statusCode": 200,
"headers": {
"Strict-Transport-Security": "max-age=31536000; includeSubDomains",
"x-ms-root-activity-id": "37b7dda1-5ee8-4a56-868a-c98bfea617ec",
"x-ms-current-utc-date": "1/28/2019 5:23:10 PM",
"X-Frame-Options": "deny",
"X-Content-Type-Options": "nosniff",
"X-XSS-Protection": "1; mode=block",
"Content-Security-Policy": "script-src 'self'",
"Date": "Mon, 28 Jan 2019 17:23:10 GMT",
"Server": "Microsoft-HTTPAPI/2.0",
"Content-Length": "2680",
"Content-Type": "application/json"
},
...
There is no location value giving me an ID to monitor with GET requests. I know I can return all the Historical requests using a GET with no ID provided - however this is going to be clunky in a function app to establish which one was the most recent etc..
Does anyone know how I could obtain the refresh Id?
Go into the HTTP Activity and click the ellipsis in the upper right-hand corner to bring up the menu, then click the "Settings" icon. In settings, disable the behavior for "Asynchronous Pattern", since you want to do the polling yourself.
This will cause the HTTP Activity to stop when it receives an HTTP Response Status Code of 202, and the Location Header will be available. With the "Asynchronous Pattern" enabled, it polls until it receives a 200, which only returns the representation of the resource (the Refresh). Unfortunately, the representation does not include its own identifier, which is hilarious in this particular use case.
Related
I've been working on here API from past one week, I've tested the geofencing and other rest services. I am trying to work on tracking, Where we have to generate a token by giving all the valid credentials. At last, I've got the token as well but when am trying to access the traces one for which the endpoint URL is
https://tracking.api.here.com/traces/v2/{trackingid}
here I've given the trackingid(deviceid) which I've used to generate an access token and included this token as a bearer in authorization I am using postman to test these, my token is valid for only 23 hours
Authorization Bearer {mytoken}
As mentioned I've also provided this x-request-id, I've no idea regarding this x-request-id but came to know about this from this thread and tried to generate uuid and use it for x-request-id
x-request-id 5506b7d0-2fe6-4967-8ad8-cf0f08fdedbf
And I am receiving the response as
{
"code": 403,
"id": "5506b7d0-2fe6-4967-8ad8-cf0f08fdedbf",
"message": "Forbidden",
"error": "Forbidden\n\nThe account does not have the correct
privileges\n"
}
The similar case even when I am trying to access the allotted geofences for that device and how many devices are in that particular geofence. I've read about whitelisting but whatever the service I am requesting for is not on their list. My account was a 90days free trial account
I am new to this hereapi Kindly correct me if I am doing anything wrong.
Kindly Help me out with this issue
Thanks in advance
--Meghana Goud
I've figured it out, I'll include the details here follow the step by step process as mentioned in the documentation
refer this HERE Tracking | API Reference
And follow the step by step process as mentioned in this documentation
The first one, you'll get your bearer token from this endpoint URL https://tracking.api.here.com/users/v2/login which is post
method and set its Content-Type to application/json and provide the username and password in JSON format and send a POST request to it
EndpointURL :https://tracking.api.here.com/users/v2/login
Headers :{"Content-Type":"application/json"}
Input :{"email":"XXXXXX", "password":"XXXX"}
Expected Response:{
"userId": "XXXXXX",
"accessToken": "XXXXX",
"tokenType": "bearer",
"expiresIn": 86399,
"refreshToken": "XXX"
}
the token is valid for only 24 hours. Now use this token for all the rest services you want to access from here-API
Now I would like to get the traces of my device using this endpointURL https://tracking.api.here.com/traces/v2/{trackingid}?count=1 , send a get request to this endpointURL by giving your trackingID, I repeat TrackingID is different from your deviceId TrackingId will be HERE-XXX(UUIDv4) whereas deviceId will be XXXX(UUIDv4)
now set the authorization to Bearer Token and pass an x-request-id which is a UUIDv4
Your request should look like
EndpointURL :https://tracking.api.here.com/traces/v2/{trackingid}?count=1
Headers :{"Authorization":"Bearer XXXXXX","x-request-id":"XXXX(UUIDv4)"}
Expected Response:{
"count": 1,
"data": [
{
"position": {
"lat": 17.44936354,
"lng": 78.36296417,
"accuracy": 45,
"alt": 539
},
"timestamp": 1531462419813,
"payload": {
"refAppData":
{
"batteryState": {
"charging": false,
"level": 52,
"temperature": 25
}
}
}
}
],
"pageToken": "1531462359711"
}
In order to update any data from your device, you'll require your device token which is generated from this endpoint URLhttps://tracking.api.here.com/v2/token you'll get your access token by OAuth1.o Authorization give the respected values as mentioned in the documentation. you'll get the response as
{
"accessToken": "XXXXXX",
"expiresIn": 86399
}
Similarly, you can test other services,
Hope this helps
Meghana
Is it ok to return extra information in http PUT response such as createdDateTime or lastUpdateTime
E.g. PUT request comes as follows
properties
{
"name": "somename"
"addr": "someaddr"
}
In response along with sending the resource representation I am sending extra information
HTTP OK or CREATED
properties
{
"name": "somename"
"addr": "someaddr"
"lastUpdateTime": "somedatetime"
}
Is this a bad practice ?
I see no problem with that. If the client needs that information, then the resource will have to include it as a property. The client can POST/PUT without it (NULL), or the server will ignore it anyway (since this is only set server-side), but it will have to reflect it afterwards.
You can always secure your API if you're going to expose it publicly (OAuth, API keys etc).
We have a web application (AngularJS and Web API) which has quite a simple functionality - displays a list of jobs and allows users to select and cancel selected jobs.
We are trying to follow RESTful approach with our API, but that's where it gets confusing.
Getting jobs is easy - simple GET: /jobs
How shall we cancel the selected jobs? Bearing in mind that this is the only operation on jobs we need to implement. The easiest and most logical approach (to me) is to send the list of selected jobs IDs to the API (server) and do necessary procedures. But that's not RESTful way.
If we are to do it following RESTful approach it seams that we need to send PATCH request to jobs, with json similar to this:
PATCH: /jobs
[
{
"op": "replace",
"path": "/jobs/123",
"status": "cancelled"
},
{
"op": "replace",
"path": "/jobs/321",
"status": "cancelled"
},
]
That will require generating this json on client, then mapping it to some the model on server, parsing "path" property to get the job ID and then do actual cancellation. This seems very convoluted and artificial to me.
What is the general advice on this kind of operation? I'm curious what people do in real life when a lot of operations can't be simply mapped to RESTful resource paradigm.
Thanks!
If by cancelling a job you mean deleting it then you could use the DELETE verb:
DELETE /jobs?ids=123,321,...
If by cancelling a job you mean setting some status field to cancelled then you could use the PATCH verb:
PATCH /jobs
Content-Type: application/json
[ { "id": 123, "status": "cancelled" }, { "id": 321, "status": "cancelled" } ]
POST for Business Process
POST is often an overlooked solution in this situation. Treating resources as nouns is a useful and common practice in REST, and as such, POST is often mapped to the "CREATE" operation from CRUD semantics - however the HTTP Spec for POST mandates no such thing:
The POST method requests that the target resource process the representation enclosed in the request according to the resource's own specific semantics. For example, POST is used for the following functions (among others):
Providing a block of data, such as the fields entered into an HTML form, to a data-handling process;
Posting a message to a bulletin board, newsgroup, mailing list, blog, or similar group of articles;
Creating a new resource that has yet to be identified by the origin server; and
Appending data to a resource's existing representation(s).
In your case, you could use:
POST /jobs/123/cancel
and consider it an example of the first option - providing a block of data to a data handling process - and is analogous to html forms using POST to submit the form.
With this technique, you could return the job representation in the body and/or return a 303 See Other status code with the Location set to /jobs/123
Some people complain that this looks 'too RPC' - but there is nothing that is not RESTful about it if you read the spec - and personally I find it much clearer than trying to find an arbitrary mapping from CRUD operations to real business processes.
Ideally, if you are concerned with following the REST spec, the URI for the cancel operation should be provided to the client via a hypermedia link in your job representation. e.g. if you were using HAL, you'd have:
GET /jobs/123
{
"id": 123,
"name": "some job name",
"_links" : {
"cancel" : {
"href" : "/jobs/123/cancel"
},
"self" : {
"href" : "/jobs/123"
}
}
}
The client could then obtain the href of the "cancel" rel link, and POST to it to effect the cancellation.
Treat Processes as Resources
Another option is, depending on if it makes sense in your domain, to make a 'cancellation' a noun and associate data with it, such as who cancelled it, when it was cancelled etc. - this is especially useful if a job may be cancelled, reopened and cancelled again, as the history of changes could be useful business data, or if the act of cancelling is an asynchronous process that requires tracking the state of the cancellation request over time. With this approach, you could use:
POST /jobs/123/cancellations
which would "create" a job cancellation - you could then have operations like:
GET /jobs/123/cancellations/1
to return the data associated with the cancellation, e.g.
{
"cancelledBy": "Joe Smith",
"requestedAt": "2016-09-01T12:43:22Z",
"status": "in process"
"completedAt": null
}
and:
GET /jobs/123/cancellations
to return a collection of cancellations that have been applied to the job and their current status.
Example 1: Let’s compare it with a real-world example: You go to a restaurant you sit at your table and you choose that you need ABC. You will have your waiter coming up and taking a note of what you want. You tell him that you want ABC. So, you are requesting ABC, the waiter responds back with ABC he gets in the kitchen and serves you the food. In this case, who is your interface in between you and the kitchen is your waiter. It’s his responsibility to carry the request from you to the kitchen, make sure it’s getting done, and you know once it is ready he gets back to you as a response.
Example 2: Another important example that we can relate is travel booking systems. For instance, take Kayak the biggest online site for booking tickets. You enter your destination, once you select dates and click on search, what you get back are the results from different airlines. How is Kayak communicating with all these airlines? There must be some ways that these airlines are actually exposing some level of information to Kayak. That’s all the talking, it’s through API’s
Example 3: Now open UBER and see. Once the site is loaded, it gives you an ability to log in or continue with Facebook and Google. In this case, Google and Facebook are also exposing some level of users’ information. There is an agreement between UBER and Google/Facebook that has already happened. That’s the reason it is letting you sign up with Google/ Facebook.
PUT /jobs{/ids}/status "cancelled"
so for example
PUT /jobs/123,321/status "cancelled"
if you want to cancel multiple jobs. Be aware, that the job id must not contain the comma character.
https://www.rfc-editor.org/rfc/rfc6570#page-25
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
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).