I am using a Private Application to update some fields of my products.
The calls are going through just fine (and returning 200 OK), however, none of the fields passed is actually being updated, and I am being returned the old product field values.
PUT https://MYKEY:MYPASS#MYSHOP.myshopify.com/admin/products/NNNNNNNN.json
{"product":{"id": NNNNNNNN,"title":"Product Name"}}
Returns:
HTTP/1.1 200 OK
{"product": {title: 'OLD TITLE'}, .... }
PS: I am using CURL, and I can read the products. Just can't update them.
Solved. You have to set 'content-type': 'application/json' in your request, which is not really documented in the API Docs.
Related
I have done some reading regarding GET and POST methods and know that GET method should be used when fetching data where the parameters are in URL. Whereas POST in general should be used to store data with data in the body.
But, I have an API that takes JSON as input. So I think I need to use POST method but what bothers me is that I won't make any changes to backend. I just need to fetch data according to the parameters in the JSON.
Would it be a bad practice to use POST method just to accept JSON even though no changes will be made?
If so, what other approaches can I take?
Thank you
Yes, you can add JSON data in the body. I'm not sure what language you are using, but for example in the requests module in Python, you can add some data to the Get request as shown in here.
This is how I use fetch to make a post with json data.
const data = {name : "toto", age : "12"}
fetch(url, {
method: "POST",
headers: { "content-type": "application/json" },
body
}).then(
console.log(data added !)
)
According to API documentation here https://backendless.com/documentation/data/rest/data_search_and_query.htm , backendless shall provide paging info in response body like this
{
"nextPage":null,
"data":[
{
"updated":null,
"created":"02/05/2014 18:13:40 GMT+0000",
"ownerId":null,
"objectId":"6FAF3CE5-6F55-1B32-FF83-D333252D0300",
"name":"Bob",
"age":20
},
{
"updated":null,
"created":"02/04/2014 19:40:10 GMT+0000",
"ownerId":null,
"objectId":"28325E9F-2DED-D3CA-FFC6-C76911AFBB00",
"name":"Frank",
"age":26
}],
"offset":0,
"totalObjects":2
}
However, when I send request to get data from table like this:
https://api.backendless.com/<version>/data/<table-name>
it returns only collection of objects (which should be in "data") and now paging info.
Adding page requests:
https://api.backendless.com/<version>/data/<table-name>?pageSize=10&offset=10
returns correct data, but still without paging info.
What I'm doing wrong? How can I access paging info?
The docs link you mention is for Backendless version which is being deprecated (there's a warning on the top of the page). Here is a link to the docs for the current version: https://backendless.com/docs/rest/doc.html#data_basic_search
Indeed, in version 4 we got rid of that additional information in the response to simplify the response object in non-REST clients. But still you can easily determine current params since you're specifying them in the request (or they're zeros in case you're not).
For designing and creating a RESTful API the following question occurs:
The API supports GET (for queries), POST (for creating), PUT (for updates) and DELETE (for deleting).
Lets assume in the database we have an article and a shop both already existing.
Now we need a rest call to link the article instance to the shop instance. Which of the following solutions is the best / most clean REST design:
/shop/id/article/id/ --> with POST
/shop/id/article/id/ --> with PUT
/shoparticlerelation/ --> with POST (object with ids in body)
/shoparticlerelation/ --> with PUT (object with ids in body)
If there is no clear answer or all solutions are equally good this may also be a valid answer if there is a clear argumentation why.
I presume in this situation you already have a collection of shops and a collection of articles, and you just wish to link two together.
One option is to expose a more db like 'resource' that presents this link, and have operations like
POST /shopArticleLinks HTTP/1.1
{ "shop" : xxx,
"article: YYY
}
I would personally look to expose it as a property of the shops and/or articles in a more natural manor, like
PUT /shop/<ID> HTTP/1.1
{ /* existing details */
"articles": [ /* list of articles */ ]
}
I've used JSON there, but of course use what ever format you want to use. I've also stuck with using PUT as you stated, but keep in mind that with PUT you should send a full replacement for the new modified version, PATCH can be used to send partial updates, but then you need to consider how you want do that, may something like
PATCH /shops/<ID>/articleLinks HTTP/1.1
{ "add" : [],
"remove : []
}
Don't forget that server side you can look at what articles are being refereed to and ensure they have a proper back pointer.
Additional thoughts
Regarding the second method, where you expose the link as a property of the shop and/or article resources. Keep in mind that it is perfectly acceptable (and in this case rather appropriate) that when you update the links in a given shop that the links in the corresponding articles are also updated.
/shop/id/article/id/
You cannot use this because at the moment you want to link them, this endpoint doesn't (or at least shouldn't) yet exist. It is the action of linking them together that should define this endpoint.
/shoparticlerelation/
You should not use this because a shoparticlerelation is not a resource / entity. Usually with rest, every named url segment represents a resource that can be CRUD-ed. /shops is a good example and so is /articles but this one isn't.
I suggest the following:
Define the following endpoints
/shops for POSTing new shops
/shops/id for operating on a single shop
/articles for POSTing new articles
/articles/id for operating on a single article
Then to link them together you can do a so called PATCH request, to update a shop's articles, or an article's shops:
PATCH /shops/1 HTTP/1.1
{
"attribute": "articles",
"operation": "add",
"value": "8" // the article id
}
and
PATCH /articles/9 HTTP/1.1
{
"attribute": "shops",
"operation": "add",
"value": "1" // the shop id
}
Based on your comments I made the assumption that an Article model has a list of Shops as attribute, and vice-versa, making this approach valid.
A PATCH request is used to modify an existing resource by specifying how and what to update. This is different from a PUT because a PUT replaces the entire resource with values from the request, however PATCH is only used to modify (not replace) a resource.
I am using the new Office365 REST API: https://msdn.microsoft.com/en-us/office/office365/api/api-catalog and am successfully querying calendar events, which include their categories as a list of strings: https://outlook.office365.com/api/v1.0/me/events
How do I query the global list of all categories associated with a calendar, as well as the colour associated with each category? The colours I setup via the Outlook client appear to persist across client instances, and yet I can't find a way to access these data via the API.
Great question! You can't access that information currently with the REST APIs, but it's a great idea.
If you're curious, all the gory details on how the category list is stored are documented in [MS-OXOCFG].
You can actually do this now with the current version of the Graph API. If you want to list the categories that have been defined for a user, you can use either of these endpoints:
GET /me/outlook/masterCategories
GET /users/{id|userPrincipalName}/outlook/masterCategories
and get something like this:
HTTP/1.1 200 OK
Content-type: application/json
Content-length: 727
{
"#odata.context":"https://graph.microsoft.com/beta/$metadata#users('8ae6f565-0d7f-4ead-853e-7db94c912a1f')/outlook/masterCategories",
"value":[
{
"id":"5a9a6aa8-b65f-4357-b1f9-60c6bf6330d8",
"displayName":"Red category",
"color":"preset0"
},
{
"id":"4b1c2495-54c9-4a5e-90a2-0ab0b31987d8",
"displayName":"Orange category",
"color":"preset1"
},
{
"id":"de912e4d-c790-4da9-949c-ccd933aaa0f7",
"displayName":"Yellow category",
"color":"preset3"
}
]
}
Let's say I have a REST API, which has basic methods to retrieve users and the photos of a user. For example:
// Get a user:
GET /user/123
// Get the photos of a user:
GET /user/123/photos
// Get a photo:
GET /photo/789
This is quite straightforward, however now I also need a method to retrieve the number of photos for a particular user. I don't want to retrieve all the photos because that would slow everything down and is not necessary. What would be the best way to do that in a REST API?
I thought about implementing something like GET /user/123/photo_count however "photo_count" is not a resource so that doesn't seem right.
How would I go about presenting this kind of information properly in a REST API?
// Get the photos of a user:
GET /user/123/photos
This does not have to actually return the photos, it could return just a list of links.
It could even be a partial list of the first n links with information on the total number, and links to get the next/prev batch.
You could do something a little "custom" like returning the count as a response header. Then to just get the count you would issue a HEAD which should return the headers with no response body (i.e.. not actually load the photos).
GET /user/123/photos
==>
Headers:
X-Count 23
Body:
<photos>
<photo id="1">...</photo>
<photo id="2">...</photo>
...
</photos>
HEAD /user/123/photos
==>
Headers:
X-Count 23
Body:
none
Like the comment on the original post, you can return the photo count as a property of your user "object". The GET /user/123 call would simply return an object/json/xml that contains the number of pictures as a property.