Which method would be more appropriate here POST or PATCH? - node.js

Let's say I have a db collection with users and I want to ADD an object to an array inside one document.
It was like this:
{
_id: "636e8e1dd710eed71565741c",
username: "test",
password: "$2b$10$/s9.kRYSax380Xrxf3xyVO9Z6Otc/WVx5kBSLKfu43/wYP.TSnzvW",
tasks: [{name: task1, status: "finished"}]
}
And I am going to make it look like this:
{
_id: "636e8e1dd710eed71565741c",
username: "test",
password: "$2b$10$/s9.kRYSax380Xrxf3xyVO9Z6Otc/WVx5kBSLKfu43/wYP.TSnzvW",
tasks: [{name: task1, status: "finished"}, {name: task2, status: "unfinished"}]
}
So which method would be more appropriate here since I'm adding a new object to an embedded array and not updating one which already exists? Thank you.

The choice between POST and PATCH depends on the path of the URL. If the path contains the _id, I'd prefer
POST /collection/636e8e1dd710eed71565741c/tasks
Content-Type: application/json
{"name": "task2", "status": "unfinished"}
However, if the _id is part of the payload, I'd prefer
PATCH /collection
Content-Type: application/json
{"_id": "636e8e1dd710eed71565741c",
"tasks#add": [{"name": "task2", "status": "unfinished"}]}
But this payload format relies on "naming conventions":
The _id serves to identify the entry to be patched.
The suffix #add means that the tasks are added to the existing array.
"tasks#change": [{"name": "task1", "status": "archived"}] would instead update the existing task.
If the server knows that each task is identified by its name, the suffixes would not be necessary:
PATCH /collection
Content-Type: application/json
{"_id": "636e8e1dd710eed71565741c",
"tasks": [{"name": "task1", "status": "archived"},
{"name": "task2", "status": "unfinished"}]}
updates the existing task and adds a new one. Or even
PATCH /collection/636e8e1dd710eed71565741c/tasks
Content-Type: application/json
[{"name": "task1", "status": "archived"},
{"name": "task2", "status": "unfinished"}]
I hope these examples help you find a suitable pattern.

Related

Adding a mailbox filter to Gmail

I am trying to add a simple mailbox filter to Gmail, and getting error 400. The response text says that "Filter doesn't have any criteria" but of course I believe I do. Here is the payload data:
{
"filter": [{
"id": "ABC12345-2",
"criteria": {
"from": "donald trump"
},
"action": {
"addLabelIds": ["TRASH"]
}
}]
}
This is the URL that I am posting to:
https://gmail.googleapis.com/gmail/v1/users/{userId}/settings/filters
There is no problem with authentication. I have tried it with and without the "id" field. Any ideas about what I am doing wrong?
I'm not sure about your actual script. So I'm not sure about the requirement of {"filter": []}. But when I saw the official document, it seems that the sample request body for the endpoint of POST https://gmail.googleapis.com/gmail/v1/users/{userId}/settings/filters is as follows, when your request body is used.
Sample request body:
{
"id": "###",
"criteria": {"from": "###"},
"action": {"addLabelIds": ["TRASH"]}
}
id: string, The server assigned ID of the filter.
criteria: object (Criteria), Matching criteria for the filter.
action: object (Action), Action that the filter performs.
In this case, even when id is not used, no error occurs.
You can also test above at "Try this API".
References:
Method: users.settings.filters.create
Resource: Filter

queryStringParameters in mock-server

I have the following url:
http://10.11.100.163:1080/v1/publish/?category=conf&product=UFED_INFIELD&serial=123&productGUIDs%5B0%5D%5Bproduct%5D=GLOBAL&productGUIDs%5B0%5D%5Bguid%5D=undefinedblabla&productGUIDs%5B1%5D%5Bproduct%5D=UFED_INFIELD&productGUIDs%5B1%5D%5Bguid%5D=undefinedblabla
As you can see there are several parameters that are formed by two names, like "productGUIDs%5B0%5D%5Bproduct%5D=GLOBAL" and this is equal to "productGUIDs[0][product]=GLOBAL"
now in the expectation file on the mock-server I am trying to create the request but without success until now.
this is what I wrote in the expectation file:
await mockServerClient(process.env.mockServerAddress , process.env.mockServerPort).setDefaultHeaders(defaultResponseHeaders, []).mockAnyResponse({
"httpRequest":{
"method": "GET",
"path": "/v1/publish",
"queryStringParameters": {
"category":["conf"],
"product":["UFED_INFIELD"],
"serial":["123"],
"productGUIDs%5B0%5D%5Bproduct%5D" : ["GLOBAL"],
"productGUIDs%5B0%5D%5Bguid%5D" : ["undefinedblabla"],
"productGUIDs%5B1%5D%5Bproduct%5D" : ["UFED_INFIELD"],
"productGUIDs%5B1%5D%5Bguid%5D" : ["undefinedblabla"],
}
},
when sending the request (GET) with POSTMAN, I get 404, means, the mock-server does not recognize the request.
any advice of how to write the query string parameters in the expectation file will be really appreaciated
The correct queryStringParameters syntax is an array of objects with name/values keys, like this:
"queryStringParameters": [
{
"name": "category",
"values": ["conf"]
},
{
"name": "product",
"values": ["UFED_INFIELD"]
},
{
"name": "productGUIDs%5B0%5D%5Bproduct%5D",
"values": ["GLOBAL"]
}
]
Here an example of an expectation in a file.yaml for a POST request with queryStringParameters. To adapt it to the GET method just delete the body and change "POST" by "GET" :
times:
remainingTimes: 1
unlimited: false
httpRequest:
method: POST
path: /accounts/login
queryStringParameters:
urlparameter1: 'value1'
body:
type: PARAMETERS
parameters:
username: myusername
password: mypassword
httpResponse:
body: {
"access_token": "e55etg9c-167e-4841-b0r3-y8fe5d1t7568",
"token_type": "bearer",
"redirectUrl": "/menu/clothes"
}
statusCode: 200
reasonPhrase: OK
The indexation is very important in the .yaml file, so be careful to have the good format for each element, otherwise it won't work.
You can find here the documentation to do expectations :
https://www.mock-server.com/mock_server/creating_expectations.html#button_match_request_by_negative_priority
Maybe you'll find your answer in the example "match request by path parameter and query parameter" in the link above.

enriching with previous references

I am trying to use the enrichment feature with an existing app.
When reading an (aggregated) feed from the client using a user_session I get a response:
{
"results": [
{
"activities": [
{
"actor": "User:67",
"foreign_id": "Saving:d6",
"id": "f1",
"object": "Item:23",
"origin": "activities:57",
"target": "List:82",
"time": "2018-11-15T09:29:25.291000",
"verb": "save"
}
],
...
Now, I would like to have the 67th User data embed in the response, using the enrichment feature. I tried, using the ruby framework:
STREAM_CLIENT.collections.upsert('User', [{id: '67', first_name: 'John', last_name: 'Doe'}])
However, reading the feed again, the response json does not contain my user data.
What am I doing wrong ?
The references that are part of the activity are not the correct format. You should use client.collections.createUserReference like described here: https://getstream.io/docs/#frontend_backend_references

Making MongoDB more 'relational'

I like using MongoDB but can't quite swallow the non-relational aspect of it. As far as I can tell from mongo users and the docs: "It's fine, just duplicate parts of your data".
As I'm worried about scaling, and basically just not remembering to update parts of the code to update the correct parts of the data, it seems like a good trade-off to just do an extra query when my API has to return the data for a user with a summary of posts included:
{
"id": 1,
"name": "Default user",
"posts_summary": [
{
"id": 1,
"name": "I am making a blog post",
"description": "I write about some stuff and there are comments after it",
"tags_count": 3
},
{
"id": 2,
"name": "This is my second post",
"description": "In this one I write some more stuff",
"tags_count": 4
}
]
}
...when the posts data looks like this below:
//db.posts
{
"id": 1,
"owner": 1,
"name": "I am making a blog post",
"description": "I write about some stuff and there are comments after it",
"tags": ["Writing", "Blogs", "Stuff"]
},
{
"id": 2,
"owner": 1,
"name": "This is my second post",
"description": "In this one I write some mores tuff",
"tags": ["Writing", "Blogs", "Stuff", "Whatever"]
}
So behind the API, when the query to get the user succeeds, I am doing an additional query to the posts collection to get the "posts_summary" data I need, and adding it in before the API sends response.
It seems like a good trade-off considering the problems it will solve later. Is this what some mongo users do to get around it not being relational, or have I made a mistake when designing my schema?
You can use schema objects as references to implement relational mapping using mongoose
http://mongoosejs.com/docs/populate.html
using mongoose ur schema would be like:
User:Schema({
_id : Number,
name : String,
owner : String,
Post : [{ type: Schema.Types.ObjectId, ref: 'Post' }]
});
Post:Schema({
_id : Number,
name : String,
owner : String,
description : String,
tags:[String]
})

What is the EntityLogicalName for activities in Microsoft Dynamics CRM

I've been able to successfully fetch items like leads, opportunities, and contacts from the dynamics API, but I've been unable to figure out how to fetch any kind of activity objects. I'm making a request that looks like this:
POST http://myAddress/myDomain/RetrieveMultiple
**headers**
Content-Type: application/json
User-Agent: our user agent
**json**
{
"Credential": {
"Domain": "thedomain",
"UserId": "theuserid",
"Password": "thepass",
"Version": "2016",
"ConnectionType": "1"
},
"EntityLogicalName": "contact",
"DateCriteria": "2000-01-01T00:00:00Z",
"DateFilterName": "modifiedon",
"Operator": ">=",
"Order": "asc",
"MaxItems": 100,
"pageNumber": 1
}
When I change the EntityLogicalName to "activitypointer", "task", "appointment", and anything else I can think of I get back an error that says "Invalid Entity name"
Activities is an abstract entity, therefore you'll need to query the concrete ones like:
"email", "phonecall", "task", etc...

Resources