How can I call beforeSave methods recursively while saving associative data in CakePHP 3? - rest

I am trying to write a REST Api using CakePHP 3.
I have two tables Documents and DocumentImages, when I send POST request with body:
{
"description": "Short Desc.",
"company_id": 2,
"department_id": 3,
"status": 0,
"document_images":[
{
"base64" : "xyz"
},
{
"base64" : "abc"
}
]
}
It saves both to Documents and DocumentImages and makes the document_id of images as it must be.
Now, I need to do something after saving the document and before saving the images, however beforeSave function in images never be called, so it saves both of the entities in DocumentsController.
What can I do for catch the event after the document saved but before the images save?
By the way, if anyone suggest a solution using CRUD I will be very appreciate.

Related

Writes from Firestore Function GraphQL query call to Firestore DB sub-collection

I have a functional prototype of an app that does the following :
A user calls a page on an app that creates a basic record for an object in a Firestore DB collection
A Firebase Function gets triggered by the "create" event
The function calls a GraphQL endpoint with a (pretty dense) query
The return of the query contains arrays of data that I want to feed back in the form of sub-collection in Firebase (and not nested arrays) for the same object
As of now and for the purpose of my initial tests, I run "for" loops that scan the data provided through the query and write those to the DB.
I am looking at saving on response times and Firestore usage metrics by optimising the code and would do with some help.
Here is an example of what I get back from the GraphQL queries :
{
"data": {
"enrichObjectQuery": {
"guid": "itemRef",
"oneOfTheDataElements": [
{
"date": "2022-01-31",
"value": 15
},
{
"date": "2022-07-31",
"value": 18
},
{
"date": "2022-12-16",
"value": 12
}
]
}
}
}
And here is an example of the code I use to inject data into Firestore. I rushed into doing something functional but I find the overall execution time to be long. The architecture is of course far from being optimal but I am pretty sure my code is part of the problem.
This is just an example and I have several of these for different data elements. Hope I did not mess anything up by making a generic example.
// enrich an object
for (let i = 0; i < data.enrichObjectQuery.oneOfTheDataElements.length; i++) {
const date = new Date(data.enrichObjectQuery.oneOfTheDataElements[i].date);
const timestamp = admin.firestore.Timestamp.fromDate(date);
db.collection("enrichObjectQuery")
.doc(data.enrichObjectQuery.guid)
.collection("oneOfTheDataElements")
.doc(data
. enrichObjectQuery.guid+data
. enrichObjectQuery.oneOfTheDataElements[i].date)
.set({
date: timestamp,
value: data.enrichObjectQuery.oneOfTheDataElements[i].value,
}, {merge: true});
}
Basically, it is doing what it is expected to do at this point.
I am now looking at optimising/refactoring all this to have the fastest and lightest code as possible... and looking for suggestions! My idea would be to avoid "loops" and inject directly an array as a sub-collection in Firestore but I am not sure to see how to do this.
(As you have probably guessed by now, I am bit of a beginner in this)

Updating relation in Hybris data using REST API, nested relation not saved

I've implemented tree structure and want to save items to database. Every item has "children" field with list of child nodes.
But if I send PUT request with something like this:
https://localhost:9001/ws410/rest/pdsfamilies/8796093098749
{
"children": [
{
"pk": "8796093164285"
}
]
}
I'm getting response 200 OK but of course "children" list doesn't update. If I pull the item using GET again, it doesn't contain that change.
What am I doing wrong?
The solution was weird nested object structure like this:
{
"children": {
"pdsFamily" : [
{
"pk": "8796093164285"
}
]
}
I don't know why another property pdsFamily was needed.
Also another weird thing is that in the response from GET I'm getting similar structure but the property is all lowercase pdsfamily... I have to create separate dtos for response and request just because of that...

Find DocumentId through Discovery GUI tool

I want to train my Discovery collection where I have already uploaded over 200 documents. I uploaded these documents through the GUI. Looking through the Discovery documentation, I know that I have will have to make API calls to train my collection since the training API has not been exposed through the GUI yet. As part of the training API calls I need to include a document that looks like this:
{
"natural_language_query": "{natural_language_query}",
"filter": "{filter_definition}"
"examples": [
{
"document_id": "{document_id_1}",
"cross_reference": "{cross_reference_1}",
"relevance": 0
},
{
"document_id": "{document_id_2}",
"cross_reference": "{cross_reference_2}",
"relevance": 0
}
]
}
My question is how should I get the documentIds for the documents that I have already uploaded? Is there a way to find this through the GUI? Or perhaps an API call that will return something like:
{
"document_name" = "MyDocument1",
"documentId" = "the_document_id_for_MyDocument1"
},
...
{
"document_name" = "MyDocumentN",
"documentId" = "the_document_id_for_MyDocumentN"
}
Or would the only way to get the documentIds would be to create a new collection and upload all of the documents through API calls directly and track the documentIds as I get them back?
Using the GUI, perform the following steps:
Input term(_id) in the "Group query results (Aggregation)"
textbox.
Under "Fields to return", select "Specify" to input
extracted_metadata
Note, that query and filter inputs should remain empty

Best way to structure my firebase database

I'm working on a project where users can post things. But, I'm wondering if my firebase database structure is efficient. Below is how my database looks like so far. I have posts child contains all the post that users will post. and each user will be able to track their own posts by having posts child in uid. Is there a better way of structuring my data? or am I good to go? Any advice would be appreciated!
{
"posts" : {
"-KVRT-4z1AUoztWnF-pe" : {
"caption" : "",
"likes" : 0,
"pictureUrl" : "https://firebasestorage.googleapis.com/v0/b/cloub-4fdbd.appspot.com/o/users%2FufTgaqudXeUciW5bGgCSfoTRUw92%2F208222E1-8E20-42A0-9EEF-8AF34F523878.png?alt=media&token=9ec5301e-d913-44ee-81d0-e0ec117017de",
"timestamp" : 1477946376629,
"writer" : "ufTgaqudXeUciW5bGgCSfoTRUw92"
}
},
"users" : {
"ufTgaqudXeUciW5bGgCSfoTRUw92" : {
"email" : "Test1#gmail.com",
"posts" : {
"-KVRT-4z1AUoztWnF-pe" : {
"timestamp" : 1477946376677
}
},
"profileImageUrl" : "https://firebasestorage.googleapis.com/v0/b/cloub-4fdbd.appspot.com/o/profile_images%2F364DDC66-BDDB-41A4-969E-397A79ECEA3D.png?alt=media&token=c135d337-a139-475c-b7a4-d289555b94ca",
"username" : "Test1"
}
}
}
Working with NoSql Data , your need to take care of few things:-
Avoid Nesting The Data Too Deep
Flatten your dataStructure as possible
Prefer Dictionaries
Security Rules [Firebase]
Try this structure:-
users:{
userID1: {..//Users info..
posts:{
postID1: true,
postID2: true,
postID3: true,
}
},
userID2: {..//Users info..},
userID3: {..//Users info..},
userID4: {..//Users info..},
},
posts: {
userID1 :{
postID1: {..//POST CONTENT },
postID2: {..//POST CONTENT },
postID3: {..//POST CONTENT },
}
}
Keep the data flat and shallow. Store data elsewhere in the tree rather than nest a branch of data under a node that is simply related, duplicating the data if that helps to keep the tree shallow.
The goal is to have fast requests that return only data you need. Consider that every time the tree changes and the client-side listener fires the node and all its children are communicated to the client. Duplication of data across the tree facilitates quick requests with minimal data.
This process of flattening the data is known as "denormalization" and this section of the Firebase Doc does a nice job of providing guidance:
https://firebase.google.com/docs/database/android/structure-data
In your example above I see posts metadata nested under "users", a nested list that grows. Every time something changes under "users" the listener will fire to update the client and all of this data will be transmitted in each response. You could instead consider to fetch the posts data from the "posts" node based on the writer's uuid.

RESTful API: Pagination issue

I've been working on a RESTful service in the last few months and I'm having issues with pagination on the client side.
On server side, many GET requests are paginated (cursor-based).
Every resource has two common fields: "updated" and "created".
E.g. let's say I want to retrieve a list of resources
GET /resources =>
{
"resources" : [
{
"id": 10,
"updated" : "iso8601_date_goes_here"
},
{
"id": 9,
"updated" : "iso8601_date_goes_here"
},
{
"id": 8,
"updated" : "iso8601_date_goes_here"
}
],
"pagination" : {
"before": 11,
"after": 7
}
}
Resources are sorted by "updated" field.
Navigating through "windows" (I called them like that, as they're not pages) is rather easy.
Also, retrieving new resources is trivial thanks to the "created"/"updated" fields.
The question is:
How can I notify the client that a resource has been deleted?
Our iOS app relies on Core Data.
After the JSON response is parsed, we create Core Data objects and then we display those via NSFetchResultController/UICollectionView combination.
P.S. What we're trying to avoid is to invalidate the whole set of data.
Thanks for your help, and have a fantastic rest of the year.