I am implementing a JSON API V1 compliant API using Grape API that uses AR as the ORM. I am a little confused on the format to create nested resources / relationships. It looks like we need to create one resource at a time and can link to exisitng resources. But we can't lets say create records for a has many relationship int he same request.
My situation: There is the Donation modal. It has many Splits. A split belong to a Fund. I need to create a donation with multiple splits.
Question: How can I structure the API according to the JSON:API recommendations?
Going through the documentation few times, I am thinking I can't make the donation in one API call and will have to create each resource separately and may be run a final commit to to trigger the donation.
Step 1: Create the donation - assume returns ID 100
POST /api/v1/donations
{ type: "donation", data: { comments: "abc" } }
Step 2: Create Split 1
POST /api/v1/splits
{
type: "split",
data: { amount: 100_00 },
relationships: {
data: [{ type: "fund", id: 5 }, { type: "donation", id: 100 }]
}
}
Finally: trigger the donation with some thing like
PATCH /api/v1/donations/100
{
type: "donation"
data: {
state: "process"
}
}
Is there a way to create it in one request?
JSON:API specification does not support creating, updating or deleting multiple resources in one request in v1.0, which is the current stable version.
The upcoming v1.1 is planned to support Extensions, which allow to extend the base specification. There is a proposal of a Atomic Operations extension provided by one of the maintainers of the specification. It's planned to be released with v1.1 as official extension.
Related
We are using Weaviate to serve e-commerce results.
Our Weaviate database stores all the products we sell.
Based on the customer and the search term we create a vector and use this to query the database. This property is called search_engine_query_vector.
For example if a customer has a habit of buying expensive products and searches for "TV" the system will most likely create a vector which is "closer" to the more expensive TVs in the database. So their first page of results is the most expensive TVs.
While this works well 99% of the time we also want ppl to be able to sort based on price.
For this we will send a query to Weaviate, where we only return products which are close to our vector(It is assumed this is all the TVs). like below:
client.query.get("Product", ["sku", "responseBody", "_additional { certainty }",
"stores { ...on Store {storeId salesPrice additionalResponseBody}}"]).with_near_vector(
{"vector": search_engine_query_vector, "similarity": TV_CUTOFF})
.limit(10)
.sort_base_on_price()
My question is there functionality in the api analogous to sort_base_on_price?
you can assume price is a number field in the schema.
Great to hear you're working with Weaviate for an e-commerce solution.
Weaviate added an initial version of sorting functionality in version 1.13!
With the Weaviate version 1.13.0 we also released the python-client v3.5.0 that introduced this functionality too. You can find the needed method documentation for python here or for other clients here!
For your use case, you could also try the following GraphQL query in the Weaviate Console:
{
Get {
Product(nearVector :{
vector:[search_engine_query_vector],
certainty: TV_CUTOFF
}
sort:{
order:desc,
path:["price_field"]
}
limit: 10
) {
sku
responseBody
stores { ...on Store {
storeId
salesPrice
additionalResponseBody
}
_additional {
certainty
}
}
}
}
I am looking for the list of endpoints available for bitbucket API regarding get the branches from a repository and a specific branch.
I was expecting to see something like:
GET /2.0/repositories/{workspace}/{repo_slug}/branches/
GET /2.0/repositories/{workspace}/{repo_slug}/branches/{branch}
So I can get the commits from a specific branch.
I know I can get commits but with this endpoint, its scope is under repository perspective.
Do you know if there are endpoints to work with branches and recursively into its hierarchy?
I looked over the documentation for API 2.0 but I did not see what I was looking for so that is why I am posting this question here.
In addition, I see some time ago that was not possible according to this answer, but it belongs to the version 1.0 of the API. Is it still true?
When hitting this endpoint:
https://api.bitbucket.org/2.0/repositories/<workspace>/<repository-name>`
# GET /2.0/repositories/{workspace}/{repo_slug}
You get as a result a JSON document. In the links attribute you got a key called branches. It is something like this:
{
"scm": "git",
"has_wiki": false,
"links": {
"watchers": {
"href": "https://api.bitbucket.org/2.0/repositories/{workspace}/{repo_slug}/watchers"
},
"branches": {
"href": "https://api.bitbucket.org/2.0/repositories/{workspace}/{repo_slug}/refs/branches"
},
....
So you can hit the endpoint and get the branches:
https://api.bitbucket.org/2.0/repositories/{workspace}/{repo_slug}/refs/branches
# GET /2.0/repositories/{workspace}/{repo_slug}/refs/branches
And get a specific branch with
https://api.bitbucket.org/2.0/repositories/{workspace}/{repo_slug}/refs/branches/<branch-name>
# GET /2.0/repositories/{workspace}/{repo_slug}/refs/branches/<branch-name>
I have a doubt what is a better option when using json api standard and communication between backend and frontend. I need only one attribute from author association - „username” and other stuff should be hidden for user that fetch this
Case a)
data: [
{
id: „100”,
type: „resource1”,
attributes: {…},
relationships: {author: {data: {id: „10”, type: „author”}}}
}
],
included: [
{
id: „10”,
type: „author”,
attributes: {username: „name”},
relationships: {resources1: {data: [{id: „100”, type: „resource1”}]}}
}
]
Case b)
data: [
{
id: „100”,
type: „resource1”,
attributes: {authorName: „name”, …},
relationships: {author: {data: {id: „10”, type: „author”}}}
}
],
included: []
Case a) looks semantic but there serve much more information in payload
Case b) is faster to get what I want from author (one attribute „username” and this is added in additional attribute: „authorName”), so also don’t need to pleas with associations in frontend side.
Any thoughts which is better practice and why?
Strictly speaking both case a and case b are valid per JSON:API specification.
In case a username is an attribute of author resource. In case b authorName is an attribute of resource1. author resource may have a username attribute in case b as well. In that case you have duplicated state.
I would recommend to only use duplicated state if you have very good reasons. Duplicated state increases complexity - both on server- as well as client-side. Keeping both attributes in sync comes with high costs. E.g. you need to update a client that resource1 changed after a successful update request, which affected the username of author resource. And the client need to parse that response and update the local cache.
There are some reasons, in which duplicating state pays off for good reasons. Calculated values, which would require a client to fetch many resources to calculate them, is a typical example. E.g. you may decide to introduce a averageRating attribute on a product resource because without a client would need to fetch all related ratings of a product only to calculate it.
Trying to reduce payload size is nearly never a good reason to accept the increased complexity. If you consider compressing and package sizes at network level, the raw payload size often doesn't make a big difference.
I am sending a request to the jsonapi node endpoint, and using the following parameter to include the "relationship" objects of those nodes for user (post author data) and user picture (avatar):
include=uid,uid.user_picture
This returns to me the json data of the nodes as well as all of the relationship objects lumped together (regardless of type) into the "included" array. The included array ends up looking like this by default:
"included": [
{
"type": "user--user",
"id": "4c717273-f903-4ffa-abe2-b5e5709ad727",
"attributes": {
"display_name": "cherylm1234",
...etc...
}
},
{
"type": "file--file",
"id": "4c717273-f903-4ffa-abe2-b5e5709ad727",
"attributes": {
"filename": "Cheryl-Fun.jpg",
...etc...
}
}
]
Context: We are trying to integrate jsonapi with an iOS app as the client/consumer.
My Problem: It's difficult to write up data models in the iOS client for these relationships (without looping and sorting every response) since they are all lumped into the same level of the "included" array. Also a problem is that each "type" will have its own set of attributes/fields so data models in iOS need to be built based on "type".
Question: Is it possible to change this structure so that all included objects are sorted by type?
I would like for the "included" array to be indexed by "type" where all objects of that type would be inside that index. Maybe something like:
included['user--user'] = [
{user-object},
{user-object},
...etc.
],
included['file--file'] = [
{file-object},
{file-object},
....etc.
],
I'm assuming this would require a custom module with some sort of hook where I could loop and sort the data before returning it to the iOS app. But, haven't been able to find any documentation on this type of json response modification.
Any help would be much appreciated.
Drupal implements the JSON:API specification. The specification specifies how a resource should be encoded. Both if it is returned as primary data or included as a relation resource.
If you want the data to be returned in another format, you would need to implement your own REST API in Drupal following another specification.
But if this is only about managing the data in a client, I would recommend to use one of the existing libraries for JSON:API specification. A list of implementations is provided at jsonapi.org/implementations/. The JSONAPI Swift package listed on that page seems to be well maintained.
I've been trying to get the HTTP verbs right lately, however I have a doubt regarding using PUT, PATCH or even POST for the following scenario.
The front end part is sending the following JSON data:
{
name: "Spanish-01",
code: "ESP01",
students: [{
IdStudent: 1,
name: "Peter Parker"
},
{
IdStudent: 2
name: "Ben Reilly",
dirtyRemove: true
}]
}
The back end code will update the Class record (e.g name and code). However, it will also delete the students with flag dirtyRemove, and those live in another table called Student.
So what's the rule here? Since PUT and PATCH according to w3.org here is for updating an existing resource. In this case the back end is both updating and deleting at the same time?
Should I use PUT or PATCH or neither?
NOTE: Don't mind about the FE part, I minimized the scope in order to get a more straightforward example
How your resources are implemented internally using tables is an implementation detail. It doesn't matter.
That said, your example payload doesn't fit PUT (to remove a student, you would omit it). It might fit PATCH, if you properly label the payload with a content type describing what semantics you expect.
Nit: the HTTP spec is not a W3 document, and the version you're looking at is outdated.