Postman GET request in order to retrieve a Mongodb entry by _id - mongodb

I'm trying to build a postman GET request in order to retrieve an entry that I have in a MongoDB by using the unique id generated in the database.
To be more precise, I am interested in writing a GET request to retrieve for example the next entry :
{
"id": "61a51cacdfb9ea1bd9395874",
"Name": "asdsd",
"Code": "asdca",
"Weight": 23,
"Price": 23,
"Color": "sfd",
"isDeleted": false
}
Does anyone have an idea how to include that id in the GET request in order to retrieve the prodcut from above?
Thanks!
EDIT :
#J.F thank you for the kind response and information provided, but unforunately, it still does not work :(.
Those are the products that I have right now, and I tried to GET the one with id = 61a51cacdfb9ea1bd9395874
And this is the response I got :
Also, this is the logic that I implemented for the GET request :
filename : product.service.ts
async getSingleProduct(productId: string) {
const product = await this.findProduct(productId);
return {
id: product.id,
Name: product.Name,
Code: product.Code,
Weight: product.Weight,
Price: product.Price,
Color: product.Price,
isDeleted: product.isDeleted };
}
private async findProduct(id: string): Promise<Product> {
let product;
try {
const product = await this.productModel.findById(id)
} catch (error) {
throw new NotFoundException('Product not found');
}
if (!product) {
throw new NotFoundException('Product not found');
}
return product;
}
filename : product.controller.ts
#Get(':id')
getProduct(#Param('id') prodId: string) {
return this.productsService.getSingleProduct(prodId)
}
EDIT2 :
#Controller('produse')
export class ProductsController {
constructor(private readonly productsService: ProductsService) {}
#Post()
async addProduct(
#Body('Name') prodName: string,
#Body('Code') prodCode: string,
#Body('Weight') prodWeight: number,
#Body('Price') prodPrice: number,
#Body('Color') prodColor: string,
#Body('isDeleted') prodIsDeleted: boolean,
) {
const generatedId = await this.productsService.createProduct(
prodName,
prodCode,
prodWeight,
prodPrice,
prodColor,
prodIsDeleted
);
return { id: generatedId };

To implement a RESTful API your endpoints has to be like this:
Verb
Path
GET
/resource
GET
/resource/:id
POST
/resource
PUT
/resource/:id
DELETE
/resource/:id
The path you want is GET /resource/:id
The id is used into route because is unique and identify a resource.
So your path can be something like:
http://localhost:8080/v1/resource/61a51cacdfb9ea1bd9395874

Related

prisma query existing item for failed unique key constraint

I have a form where clients can register for contests. They submit their name and email address, and the registration gets stored in a table in the database which has a composite primary key of the contestId and the clientId.
If someone submits the form a second time (i.e., tries to register for the same contest a second time), Prisma throws a failed constraint error. That's fine, and even expected, but I'd like to return the existing entry, and am having a hard time constructing the query.
Schema:
model Client {
id Int #id #default(autoincrement())
email String #unique
first String?
last String?
registrations Registration[]
}
model Contest {
id Int #id #default(autoincrement())
name String #unique
registrations Registration[]
}
model Registration {
contest Contest #relation(fields: [contestId], references: [id])
contestId Int
contestant Client #relation(fields: [clientId], references: [id])
clientId Int
points Int
##id ([contestId, clientId])
}
Registration:
try {
const registration = await prisma.registration.create({
data: {
points: 1,
contest: {
connectOrCreate: {
where: {
name: contest,
},
create: {
name: contest,
}
}
},
contestant: {
connectOrCreate: {
where: {
email: email,
},
create: {
first: first,
last: last,
email: email,
},
},
},
}
});
return res.status(201).send({ ...registration});
}
For new registrants that works, but if the registration already exists, I end up in the catch block. I assume this is the right way to do this — as opposed to, say, querying for existence first, because that seems expensive given that it's likely to be very rare that someone accidentally tries to re-register — but if this isn't a best practice on how to handle things, I'm open to other suggestions.
In the catch block, I then need to find the existing entry, but neither of the two things I've tried have worked:
catch (error) {
// entry already exists
if ('P2002' === error.code) {
const registration = await prisma.registration.findUnique({
where: {
contest: {
is: {
name: contest,
},
},
contestant: {
is: {
email: email,
},
},
},
})
return res.status(200).send(...registration);
}
return res.status(500).end(`Register for contest errorr: ${error.message}`);
}
complains Argument where of type RegistrationWhereUniqueInput needs exactly one argument, but you provided contest and contestant.
And
const registration = await prisma.registration.findUnique({
where: {
contestId_clientId: {
contest: {
is: {
name: contest,
},
},
contestant: {
is: {
email: email,
},
},
},
},
})
complains
Unknown arg `contest` in where.contestId_clientId.contest for type RegistrationContestIdClientIdCompoundUniqueInput. Did you mean `contestId`?
Unknown arg `contestant` in where.contestId_clientId.contestant for type RegistrationContestIdClientIdCompoundUniqueInput. Did you mean `contestId`?
Argument contestId for where.contestId_clientId.contestId is missing.
Argument clientId for where.contestId_clientId.clientId is missing.
I feel like this latter approach of using Prisma's auto-generated contestId_clientId is directionally right, but how do I construct the Prisma query to find it, starting from having the contest name and client email?
Instead of finding a unique record from the registration model, you can do a query something like this to find the Contest and Client details. The only valid argument for findUnique in the registration model would be: contestId_clientId and you can only pass contestId and clientId in them, other values are not allowed.
const registration = await prisma.client.findUnique({
where: {
email: 'email',
},
include: {
registrations: {
select: {
contest: contest,
points: true,
},
},
},
});

graphql with prisma use where in update func with relation field

schema.prisma file I need help how can I update a post based on 2 conditions? The user id that I get from userId which belongs to user tab and post id which belongs to on other post table
updatePost: async (parant, args, context) => {
const { userId } = context;
const postExist = await context.prisma.post.findUnique({
where: {
id: args.id,
author:{
id: userId
}
}
})
if (!postExist) {
throw new Error ('post not found')
}
const updatedPost = await context.prisma.post.update({
data:{
...args.data
}
})
return updatedPost
},
error code:
"message": "\nInvalid `context.prisma.post.findUnique()` invocation
Argument where of type PostWhereUniqueInput needs exactly one argument, but you provided id and author. Please choose one. Available args: ",
"type PostWhereUniqueInput {",
" id?: Int",
"Unknown arg `author` in where.author for type PostWhereUniqueInput. Available args:",
"",
"type PostWhereUniqueInput {",
" id?: Int",
"}",
You should use context.prisma.post.findFirst()
context.prisma.post.findUnique will only accept fields with #unique field in your schema file. In this case, that is only your Post id.

Why does GraphQl return null?

I am trying to create an API with MongoDB, Express Js, Node and GraphQl. I have a collection called characters, with the following schema:
const CharacterSchema = Schema({
page:{
type: Number,
required: true
},
data:{
type: Array,
required: true
}
});
I have 25 objects in my database with the above schema. I have a query to query the characters, passing the page number by parameter:
type Character {
_id: ID
name: String!
status: String!
species: String!
type: String!
gender: String!
origin: String!
image: String!
episode: [String]
location: String!
created: String!
}
type Page {
page: Int!
data: [Character]!
}
type Query {
characters(page: Int!): Page!
}
And this is its resolver:
export const resolvers = {
Query: {
characters: async (_, args) => {
let data = await Character.findOne({ page: args.page });
return data;
},
},
};
This is the query Im using to fetch the data:
query($page: Int!) {
characters(page: $page) {
page
data {
name
status
species
type
gender
origin
image
episode
location
created
}
}
}
Executing the query by passing the page number, it returns perfectly the information I ask for.
Now I want to get only one character by its ID. I created a query and a type to fetch only one character by its id:
type CharacterById {
result: Character
}
type Query {
characters(page: Int!): Page!,
character(id: ID): CharacterById
}
This is its resolver:
export const resolvers = {
Query: {
//this works perfectly
characters: async (_, args) => {
let data = await Character.findOne({ page: args.page });
return data;
},
//returns obj but show me null
character: async (_, args) => {
//first method returns the object perfectly
let data = await Character.aggregate([
{ $unwind: "$data" },
{ $match: { "data._id": args.id } },
]);
return data[0].data // returns object
//second method returns the object perfectly
let data = await Character.findOne({"data._id": args.id})
let character = data.data.find(item => item._id === args.id)
return character // returns object
},
},
};
I explain the above: The query “character” is the resolver that I created to get from the database the character with the id passed by parameter.
I try it with two methods. Both of them return me perfectly the object with the id passed by parameter, but when I try to use the query:
query($characterId: ID!) {
character(id: $characterId) {
result {
name
status
species
type
gender
origin
image
episode
location
created
}
}
}
It returns me a null, when it should return me the object:
{
"data": {
"character": null
}
}
why doesn't it bring me the object?
please help me I am very stressed and frustrated that this is not working for me :(

How to pass array to graphql mutation using axios

I have created a mutation that accepts an array of objects. I tested it with an apollo client and it's working fine in my apollo client query is looks like this.
mutation {
createStudent(createStudentInput: [{
name:"Jhone Doe"
email:"Jhonedoe#gamil.com"
dob:"1996-01-21"
},
{
name:"Jhone Doe1"
email:"Jhonedoe1#scl.com"
dob:"2000-01-22"
}
]) {
id,
name
dob
}
}
But when I try to perform the mutation using Axios it's throwing an error Request failed with status code 400.this is the qraphql query I'm passing to the Axios. I can't figure out what I am doing wrong here. Please note that records is an array of objects
const graphqlQuery = {
query: `
mutation {
createStudent(createStudentInput:${records}) {
id,
name
dob
}
}`,
variables: {
},
};
My Axios request
try {
const results = await axios({
url: endpoint,
method: 'post',
headers: headers,
data: graphqlQuery,
});
return results;
} catch (error) {
console.log(`error occured:${error}`);
}
}

How to retrieve added doc data in Firestore?

I have such code where I can get new inserted doc id:
db.collection("cities").add({
name: "Tokyo",
country: "Japan"
})
.then(function(docRef) {
console.log("Document written with ID: ", docRef.id);
})
.catch(function(error) {
console.error("Error adding document: ", error);
});
Is it possible to get data from ref?
Yes you can do it like this:
.then(function(docRef) {
db.collection("cities").doc(docRef.id).get()
.then(snap => {
console.log('Here is the document you wrote to', snap.data()
})
})
Granted it requires another read which you probably didn't want
I found solution
static async createUserPofile(uid) {
const db = Firebase.firestore(),
date = Firebase.firestore.FieldValue.serverTimestamp(),
data ={
user_id: uid,
creation_time: date,
update_time: date
},
docRef = await db.collection("user_profiles").add(data),
get = await docRef.get();
return get.data();
}
We could retrieve added or updated data using this function:
function dataToObject(fDoc){
return { ...fDoc.data(), id: fDoc.id }}
We should chain 'get' method to retrieve added or updated firestore data:
let fDoc = await db.collection("cities").add({
name: "Tokyo",
country: "Japan"
}).get()
Use it to transform your snapshot to an object:
const upserData = dataToObject(fDoc)