I was looking at the billing API for IBM Cloud, it only supports months url.
here is my code:
def processResourceInstanceUsage(account_id, billMonth):
METERING_HOST="https://metering-reporting.ng.bluemix.net"
USAGE_URL="/v4/accounts/"+account_id+"/resource_instances/usage/"+billMonth+"?_limit=100&_names=true"
url=METERING_HOST+USAGE_URL
headers = {
"Authorization": "{}".format(iam_token),
"Accept": "application/json",
"Content-Type": "application/json"
}
response=requests.get(url, headers=headers)
print ("\n\nResource instance usage for first 100 items")
return response.json()
Is there a way to get billing data out for a year? I tried inputting just 2019 instead of 2019-03 but got an error.
Check out the IBM Cloud API docs. There is a Usage Metering and a Usage Reporting API. The former is for a specific service and is more flexible. The latter, for usage reporting, is per account, org, resource group, etc. All requests have to specify the usage month. Thus, there is no request type to report for a year.
IMHO the reasoning behind is that there are many types of "year" and hence monthly reporting is flexible. As a consequence, you would need to perform the requests for each month and sum it up on your own.
Related
I've found that Http 207 can be used for bulk insert/delete/... etc. operations where we potentially have multiple items being inserted and partial success is ok from business perspective.
I wonder if the same thing applies if we have API Post calling some external services?
Example business scenario:
We have HttpPost endpoint that is creating an order.
HttpPost:
/api/order/
Now let's assume that this endpoint besides creation of an Order would be calling external service to also print a label for that order and another one to send some kind of confirmation via REST to external 3rd party system.
Now in this scenario we assume that creation of Order is a must for the success of this operation but both printing and external REST call can return error message. Potentially that is besides our control.
Now from what I've read the options on how to return this information would be:
Http 200 with some kind of object containing necessary information. For example:
{
"isSucess": true,
"isFailure": true,
"erorMesage": "string"
}
Make the endpoint more RESTful and separate it into 3 actions which would be called, but in this case this is not applicable (at least from my perspective) because all of those things are tightly coupled from business perspective and they should be bound together
Return 5xx error. 502 since not all of the actions succeeded and there were some internal problems, but what if one failed action is 502 and another 503
Return 207 error with proper error response for each of the actions (Order creation: 200, Printing: 502, External 3rd party: 502)
Now I wonder which would be most suitable ? I'm kind of leaning towards 502 error or 207 since they in my opinion provide the most information about the actual state of the system.
This is a design question for how to use REST web service for a nested distributed transaction. There are many suitable answers.
Here is my take on this, where I address each of your points, while referring to the REST spec.
HTTP code 207 is not a good idea - This return code (207) is specified for systems that support WebDAV (https://en.wikipedia.org/wiki/WebDAV) extension on HTTP. WebDAV is distributed, however it is a specification that
allows user agents to collaboratively author contents directly in an
HTTP web server
WebDAV is not exactly built for distributed transactions. Servers that can handle return code 207 need to have the WebDAV module installed in them. You may not even get support in several REST libraries for this return code. For example this API docs does not have code 207. https://docs.oracle.com/javaee/7/api/javax/ws/rs/core/Response.Status.html (this is an edge case, but it helps make the point).
I prefer not use HTTP 50x if the request is partially fulfilled. Lets take the case when the server has created the order but could not post it to the third party REST server (either that server was down or network error). Here is the spec for 50x errors https://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html:
"Response status codes beginning with the digit "5" indicate cases in
which the server is aware that it has erred or is incapable of
performing the request. "
The server is not at fault here. It has created the entity.
My suggestion is to return HTTP cod 202 on POST /api/order/, return a reference to the order and process the steps asynchronously. There are multiple transactions involved in this request - printing label, updating third party REST endpoint, etc. These can be updated in the "order" resource.
For example, the POST /api/order/ can return in this format:
HTTP STATUS 202 (Accepted)
{
"order": {
"id": "1234567"
}
}
The client should check for the complete status with GET /api/order/, which will return the individual status:
{ "id": 1234567, "label_printed": "failed", "third_party_updated":
"success"}
If any of the sub-transactions of an order has failed and should be reprocessed, it is an update on the existing order, and a call to PUT /api/order/, because the PUT method is to update the resource. The server will take the PUT request and retry the transactions as needed.
Here are some additional answers that are suitable for this question:
Transactions in REST?
Transactions across REST microservices?
It may be opinionated and not belong here, but I don't seem to find any info about this.
I have a 'sales' resource so I can GET, POST, PUT, DELETE sales of my store.
I want to do a dashboard with information about those sales: e.g the average sales per day of the last month.
Since REST is resource-oriented, that means I have to manually retrieve all sales of the last month and calculate the average per day on client using GET /sales?sale_date>=...? That doesn't seem optimal, since I could have thousands of sales in that period of time.
Also, I don't think REST can allow a URL like GET /sales/average-per-day-last-month. What is the alternative of doing this?
I don't think REST can allow a URL like GET /sales/average-per-day-last-month
Change your thinking - that's a perfectly satisfactory URL for a perfectly satisfactory resource.
Any information that can be named can be a resource -- Fielding, 2000
"Any information that can be named" of course includes "any sales report that you can imagine".
GET /sales/average-per-day-last-month HTTP/x.y
That's perfect. Depending on your needs, you might also want to have other resources that are the "average-per-day" report for specific months.
GET /sales/2021-02/average-per-day HTTP/x.y
REST doesn't constrain your resource model at all; and it doesn't constrain your resource identifier design beyond expecting conformance to the production rules described by RFC 3986.
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.
There is a change to our business logic, where earlier with one of the APIs we use to return a list, for eg. list of employees. Recently we introduced authorization checks, to see if a particular user has permission to view a specific employee.
If say there are 10 employees that should be returned through method GET, due to the missing permission only 5 are returned. The request itself in this case is successful. I am currently not sure how to pass on the information back to the client that there were 5 employees that are filtered out due to missing permission.
Should this be mapped to HTTP status codes? If yes, which status code fits this? Or this is not an error at all?
What would be the best approach in this case?
A status code by itself wouldn't be sufficient to indicate the partial response. The status code 206 sounds close by name but is used when a client specifically requests a partial set of data based on headers.
Use 200. The request was fulfilled successfully after all, and the reason for the smaller set of data is proprietary to your API so extra metadata in the response to indicate a message might be sufficient.
Assuming JSON response:
{
"data": [ ... ],
"messages": [
"Only some data was returned due to permissions."
]
}
If you have many consumers and are worried about backward compatibility you may also want to provide a vendor specific versioned JSON media type:
"Content-Type": "application/vnd.myorg-v2+json"
I am starting a new project and I was trying to figure out if I should follow a RESTful approach or not. By reading different sources on the internet I am getting more and more confused on how a truly RESTful approach should be. Some people say that the REST request (ie, both the URI and the rest of the content of the HTTP request) should never describe an action with something other than the HTTP verbs. Some others say that since the HTTP verbs are limited, the HTTP request body can provide additional info regarding which action need to be applied on the data described by the URI. Which of the two is correct? I will give you a simplified description of the software I am trying to build and how I think it should implemented with REST: The user must be able to upload/delete/edit data on the server. Then, he must be able to perform 10 different kinds of analysis (analysis01-analysis10) on the server in the form of jobs. So, the user will be submitting jobs to the server. When the jobs are finished the user will be able to get the results of the analysis. So here is how I think is the right way of implementing this in REST:
Datasets:
POST /datasets/ - To create/upload a new dataset
GET /datasets/ - To get a list of all the available datasets.
GET /datasets/01 - To get info about dataset 01
DELETE /datasets/01 - To delete dataset 01
Jobs:
POST /analysis01_jobs/ - Submit a new job for analysis01
GET /analysis01_jobs/ - Get a list with all the submitted analysis01 jobs
GET /analysis10_jobs/ - Get a list with all the submitted analysis10 jobs
GET /analysis01_jobs/01 - Get the status of job '01' which performs analysis of type 01
DELETE /analysis10_jobs/01 - Delete/Cancel job '01' which performs analysis of type 10
As you can see each type of analysis has a different REST URL path for the jobs. I was thinking to change this and put all jobs under the same path: "/analysis_jobs/" and specify the type of analysis I want inside the HTTP header. But this will imply the type of action I want the server to perform. Thus this this is not RESTful any more. Right or wrong?
When a job is complete it will produce a "result" resource. So the REST API for this will be something like this:
- There is no POST here because only the job that runs on the server can generate results.
GET /analysis01_results/ - To get a list of all the available results from analysis01 jobs
GET /analysis01_results/01 - To get the results of a job that performed analysis of type 01. The body of the HTTP response will also contain info about the "parent" job and data.
DELETE /analysis01_results/01 - To delete the above results.
Is the above design RESTful?
Thank you in advance!
REST is about machine to machine communication. If you don't have at least 2 different clients I don't think it will worth the effort to implement a REST service.
Some people say that the REST request (ie, both the URI and the rest of the content of the HTTP request) should never describe an action with something other than the HTTP verbs. Some others say that since the HTTP verbs are limited, the HTTP request body can provide additional info regarding which action need to be applied on the data described by the URI. Which of the two is correct?
You should read the Fielding dissertation, it is the only true source of knowledge. :D
Both can be wrong. The second one is closer to the truth. If you need to describe a new action, you can always define a new resource and use it with the existing HTTP verbs. For example ANALYZE /datasets/1 can be described with POST /analysis/ {dataset: {id: 1}}.
Be aware that we are talking here about hyperlinks:
POST /datasets/ - To create/upload a new dataset
This is an action, but this is a hyperlink as well in the representation of the /datasets/, which you can access with GET /datasets/. What you can add to the body is the To create/upload a new dataset part, so the client won't need to know anything about the URI structure to understand what the link does.
{
href: "/datasets/",
method: "POST",
rel: "/docs/datasets/create"
}
You can access the form description with GET /docs/datasets/create. (Currently ppl are working on a standard format, to describe these descriptions, e.g. RDF + Hydra. But that is not production ready currently.)
Ofc. you can expand the description if you want:
{
href: "/datasets/",
method: "POST",
rel: "/docs/datasets/create",
label: "Create a new dataset",
description: "You can create a new dataset by sending this form.",
fields: {
label: {
type: "string",
label: "Title",
description: "You can give a title to the dataset here.",
...
},
records: {
type: "array",
...
}
}
}
but it is easier to generate a documentation if you describe everything in a docs file, probably in JSON-LD for the REST clients and in HTML for the 3rd party developers of the clients.
POST /analysis01_jobs/ - Submit a new job for analysis01
GET /analysis01_results/ - To get a list of all the available results from analysis01 jobs
GET /analysis01_results/01 - To get the results of a job that performed analysis of type 01. The body of the HTTP response will also contain info about the "parent" job and data.
I would rather use
POST /jobs/ {analysis: {id: "01"}}
GET /analysis/01/jobs
GET /jobs/2345/result
You are going in the right direction but still you can moderate it.
1-
Is REST a good solution for my application?
Yes and you can compare it .REST vs SOAP on this question
2-
Use PUT for Creating or Adding a resource or Job instead of POST.
Resources are manipulated using a fixed set of four create, read, update, delete operations: PUT, GET, POST, and DELETE. PUT creates a new resource, which can be then deleted by using DELETE. GET retrieves the current state of a resource in some representation. POST transfers a new state onto a resource. See Responding to HTTP Methods and Requests for more information.
Source Oracle docs