I use the self href from my HAL resources on the client side to find the right path for the CRUD operations. In single(ton) resources this is working fine (see the address resource below, the _links containing the self href is included in the embedded resource) but when it comes down to collections this is a different story. The _links of a collection are not rendered when the collection is in _embedded.
Earlier I worked around this problem by reading the url form the first child. But this is not sufficient. In case the collection is empty I only have
an empty array with no possibility to extract the url like that. If I want to create a new item in the collection I would like that my client knows where to send data using POST by reading the self href from _links. Is it a good idea to include the _links to my collection like this:
{
"_links": {
"self": {
"href": "http://example.com/api/v1/users/1"
}
},
"_embedded": {
"contacts": {
Now I have access to the self href here:
"_links": {
"self": {
"href": "http://example.com/api/v1/users/1/contacts"
}
},
"_embedded": {
"contacts": [
{
"_links": {
"self": {
"href": "http://example.com/api/v1/users/1/contacts/2"
}
},
"id": "2",
"name": "John Smith"
},
{
"_links": {
"self": {
"href": "http://example.org/api/v1/users/1/contacts/3"
}
},
"id": "3",
"name": "Jane Doe"
}
],
}
},
"address": {
"_links": {
"self": {
"href": "http://example.com/api/v1/addresses/1"
}
},
"street": "Bakerstreet 11",
"postal code": "123456",
"city": "Some city",
"country": "Some country",
}
},
"id": "1",
"name": "John Doe"
}
EDIT (one year later)
In the end I solved this by always adding the links of embedded resources to the parent resource. So in the example above my response object would look like this:
{
"_links": {
"self": {
"href": "http://example.com/api/v1/users/1"
},
"contacts": {
"href": "http://example.com/api/v1/users/1/contacts"
},
"address": {
"href": "http://example.com/api/v1/addresses/1"
}
},
"_embedded": {
"contacts": [
{
"_links": {
"self": {
"href": "http://example.com/api/v1/users/1/contacts/2"
}
},
"id": "2",
"name": "John Smith"
},
{
"_links": {
"self": {
"href": "http://example.org/api/v1/users/1/contacts/3"
}
},
"id": "3",
"name": "Jane Doe"
},
],
"address": {
"_links": {
"self": {
"href": "http://example.org/api/v1/addresses/1"
}
},
"street": "Bakerstreet 11",
"postal code": "123456",
"city": "Some city",
"country": "Some country",
}
},
"id": "1",
"name": "John Doe"
}
So no matter whether I embedded the resources or not I always know where they are located. And for the contacts collection I will have the link to my collection endpoint in the _links array and the contacts themselves in _embedded.
Yes. It's not only good practice to do so; it's recommended by the HAL spec:
Each Resource Object SHOULD contain a 'self' link that corresponds with the IANA registered 'self' relation (as defined by RFC5988) whose target is the resource's URI.
A collection of resources is itself a resource, don't forget.
Related
I am trying to create an application. I created a custom post type and added custom fields using ACF. When I try to post to save the data, it doesn't save it and when I create one inside wordpress and request it using it's ID, it doesn't show the data in the response.
Below is the JSON (I tried with acf, fields and with leaving everything outside of an object), response and URL.
{
"title": "title 7",
"acf": {
"feeling": "ok",
"feeling_at_the_moment": "relieved",
"what_have_you_been_doing": "chores",
"cognitive_distortions": "",
"challenge": "",
"interpretation": "",
"feeling_now": "",
"email": "gmail.com"
}
}
{
"id": 4392,
"date": "2022-12-03T19:49:14",
"date_gmt": "2022-12-03T19:49:14",
"guid": {
"rendered": "/?post_type=mood_tracker&p=4392",
"raw": "/?post_type=mood_tracker&p=4392"
},
"modified": "2022-12-03T19:49:14",
"modified_gmt": "2022-12-03T19:49:14",
"password": "",
"slug": "",
"status": "draft",
"type": "mood_tracker",
"link": "/?post_type=mood_tracker&p=4392",
"title": {
"raw": "title 7",
"rendered": "title 7"
},
"content": {
"raw": "",
"rendered": "",
"protected": false,
"block_version": 0
},
"featured_media": 0,
"template": "",
"meta": {
"_mi_skip_tracking": false
},
"permalink_template": "/mood_tracker/%pagename%/",
"generated_slug": "title-7",
"_links": {
"self": [
{
"href": "/wp-json/wp/v2/mood_tracker/4392"
}
],
"collection": [
{
"href": "/wp-json/wp/v2/mood_tracker"
}
],
"about": [
{
"href": "/wp-json/wp/v2/types/mood_tracker"
}
],
"wp:attachment": [
{
"href": "/wp-json/wp/v2/media?parent=4392"
}
],
"wp:action-publish": [
{
"href": "/wp-json/wp/v2/mood_tracker/4392"
}
],
"wp:action-unfiltered-html": [
{
"href": "/wp-json/wp/v2/mood_tracker/4392"
}
],
"curies": [
{
"name": "wp",
"href": "https://api.w.org/{rel}",
"templated": true
}
]
}
}
https://link.com/wp-json/wp/v2/mood_tracker
As per the ACF document. Make sure this is turned on
Make sure you do the same while you are creating the custom field group in case it overwrites the general settings
Sometimes I need to republish the already created posts so they get affected
If my data structure looks like this:
documents.json:
{
"-NG8qzvgs46A5gojZbJO": {
"-NG8r-2q1-47MWK35aT2": {
"description": "My Description",
"title": "My Title"
},
"author": "jim",
"date": "05/11/2022"
},
"-NG8ta4xpHGZxA4JRUQZ": {
"-NG8ta9e90ChdMQclirn": {
"description": "My Description",
"title": "My Title tom"
},
"author": "tom",
"date": "04/11/2022"
},
"-NG8tjfP_TYJHZcjouY8": {
"-NG8tjiryoxnWbb4wwQQ": {
"description": "My Description ccc",
"title": "My Title jim"
},
"author": "jim",
"date": "05/11/2022"
}
}
How to get all the entries where author="jim"?
This does not work:
https://testing-11f41-default-rtdb.firebaseio.com/documents.json?orderBy="author"&equalTo="jim"
Is it possible using Firebase REST API?
Thanks in advance.
When I access the URL you give, I get this response:
{
"error" : "Index not defined, add ".indexOn": "author", for path "/documents", to the rules"
}
As this message says, you need to add an index to allow this query.
In your rules:
{
"rules": {
...
"documents": {
".indexOn": "author"
}
}
}
I'm developping an application using MS Graph API on a sharepoint site.
I'm trying to build the URL that allow me to find a drive item in a library with a colum param.
Actually I built this get URL to retrieve the drive items in the library:
https://graph.microsoft.com/v1.0/sites/{mainSite}:/sites/{subsite}:/lists/{libname}/items
I obtain a JSON with all files.
{
"#odata.context": "https://graph.microsoft.com/v1.0/$metadata#Collection(microsoft.graph.list)('myLib')/items",
"value": [
...
{
"#odata.etag": "\"7773c0de-bed1-425b-9065-2310c600757b,6\"",
"createdDateTime": "2019-11-21T09:19:57Z",
"eTag": "\"7773c0de-bed1-425b-9065-2310c600757b,6\"",
"id": "24",
"lastModifiedDateTime": "2020-05-27T09:09:05Z",
"webUrl": "https://xxxx.sharepoint.com/sites/SUBSITE/myLib/Cartouche.docx",
"createdBy": {
"user": {
"email": "xxx#xxx.fr",
"id": "5fe24d57-1357-4fef-9cae-bfd79b0bf831",
"displayName": "David Vera"
}
},
"lastModifiedBy": {
"user": {
"email": "dvera#dsidiff.fr",
"id": "5fe24d57-1357-4fef-9cae-bfd79b0bf831",
"displayName": "David Vera"
}
},
"parentReference": {
"id": "1836034d-8a35-4488-995e-a7fe9cd30b4c",
"siteId": "xxx.sharepoint.com,82a2327c-e2cf-4d30-b529-31c3bcdcda5e,fbi3zrs9-b07a-4777-945b-3b42c5c876d"
},
"contentType": {
"id": "0x010100E4AD49D3A8873645A2803D49D2A4BF60"
}
},
...
]
}
I tried to use filter :
https://graph.microsoft.com/v1.0/sites/{mainSite}:/sites/{subsite}:/lists/{libname}/items?expand=fields(select=CODE_ANNONCEUR,val)&filter=fields/val eq 'myself'
It returns me :
{
"error": {
"code": "-1, Microsoft.SharePoint.Client.InvalidClientQueryException",
"message": "The expression « fields (select ») is not valid.",
"innerError": {
"request-id": "c3edc510-2d63-4f21-86cd-a377fb02d324",
"date": "2020-05-27T09:44:23"
}
}
}
I solved the issue this way :
https://graph.microsoft.com/v1.0/sites/xxx.sharepoint.com:/sites/yyy:/lists/zzz/items?expand=fields/CODE_ANNONCEUR&filter=fields/CODE_ANNONCEUR eq 'stringExpected'
I'm thinking of using the JSONAPI standard for the design of our API. One thing this API must be able to do, is accept a compound document (several layers deep) and create it. The root object owns all descendants ('to-many' relationships) which the server knows nothing about at that point, so it's not possible for the client to provide an id.
Is this supported by the specification or does the client have to issue http requests for every object in the document in order?
from http://jsonapi.org/format/#document-compound-documents
Compound documents require "full linkage", meaning that every included
resource MUST be identified by at least one resource identifier object
in the same document. These resource identifier objects could either
be primary data or represent resource linkage contained within primary
or included resources. The only exception to the full linkage
requirement is when relationship fields that would otherwise contain
linkage data are excluded via sparse fieldsets.
{
"data": [{
"type": "articles",
"id": "1",
"attributes": {
"title": "JSON API paints my bikeshed!"
},
"links": {
"self": "http://example.com/articles/1"
},
"relationships": {
"author": {
"links": {
"self": "http://example.com/articles/1/relationships/author",
"related": "http://example.com/articles/1/author"
},
"data": { "type": "people", "id": "9" }
},
"comments": {
"links": {
"self": "http://example.com/articles/1/relationships/comments",
"related": "http://example.com/articles/1/comments"
},
"data": [
{ "type": "comments", "id": "5" },
{ "type": "comments", "id": "12" }
]
}
}
}],
"included": [{
"type": "people",
"id": "9",
"attributes": {
"first-name": "Dan",
"last-name": "Gebhardt",
"twitter": "dgeb"
},
"links": {
"self": "http://example.com/people/9"
}
}, {
"type": "comments",
"id": "5",
"attributes": {
"body": "First!"
},
"links": {
"self": "http://example.com/comments/5"
}
}, {
"type": "comments",
"id": "12",
"attributes": {
"body": "I like XML better"
},
"links": {
"self": "http://example.com/comments/12"
}
}]
}
I have a resource (e.g. posts) which has a to-many relationship to other resources (e.g. comments). I do not need any fields of the related resource but their self-links (to fetch them asynchronously on demand). The response should look something like this:
{
"links": {
"self": "http://example.com/posts/1?xxx",
},
"data": [{
"type": "posts",
"id": "1",
"attributes": {
"title": "JSON API paints my bikeshed!"
},
"relationships": {
"comments": {
"links": {
"self": "http://example.com/posts/1/relationships/comments",
"related": "http://example.com/posts/1/comments"
},
"data": [
{ "type": "comments", "id": "5" },
{ "type": "comments", "id": "12" }
]
}
},
"links": {
"self": "http://example.com/posts/1"
}
}],
"included": [{
"type": "comments",
"id": "5",
"links": {
"self": "http://example.com/comments/5"
}
}, {
"type": "comments",
"id": "12",
"links": {
"self": "http://example.com/comments/12"
}
}]
}
My question is how should the URL for the request look like?
My idea would be to include the comments and then use an empty sparse fieldset to avoid getting any comment fields but just the self link (+id, type).
Hence, it should look something like http://example.com/posts/1?include=comments&fields[comments]=[].
So I need something like an empty sparse fieldset.
The JSON API specification does not say much about sparse fieldsets (http://jsonapi.org/format/#fetching-sparse-fieldsets) and their relation to links.
The JSON API was able to answer my question.
In short, the correct way to specify an empty sparse fieldset would be:
http://example.com/posts/1?include=comments&fields[comments]=
There's a discussion going on about whether to include the links to individual relationship items in the relationship object:
{
"links": {
"self": "http://example.com/posts/1",
},
"data": [{
"type": "posts",
"id": "1",
"attributes": {
"title": "JSON API paints my bikeshed!"
},
"relationships": {
"comments": {
"links": {
"self": "http://example.com/posts/1/relationships/comments",
"related": "http://example.com/posts/1/comments",
"item": [ "http://example.com/comments/5", "http://example.com/comments/12" ]
},
"data": [{
"type": "comments",
"id": "5",
"links": {
"about": "http://example.com/comments/5"
}
}, {
"type": "comments",
"id": "12",
"links": {
"about": "http://example.com/comments/12"
}
}]
}
},
"links": {
"self": "http://example.com/posts/1"
}
}]
}