What is the best way to send what the customer ordered in the payment intent? - stripe-payments

In this tutorial, the docs teach how to use stripe with react + express.
I'm currently using the field `metadata` to put a JSON string with the order detail so that the webhook can know what the user ordered:
await stripe.paymentIntents.create({
currency: "brl",
amount: getTotal(orderItems),
payment_method_types: ["card", "boleto"],
receipt_email: userEmail,
description: getSummary(orderItems),
metadata: {
userId,
reports: getReportMetadata(orderItems),
},
});
But stripe put a limit of 500 characters in this field. To prevent some edge case buy orders from being blocked, I transform each field of the JSON array in a one-letter word before sending to this function. But it seems that this is not the right field to do it. Is there a better way of doing this?

It's simply a length limitation on that field. You can consider splitting your information into multiple fields, or save your information into your own DB and only save a reference ID into metadata. Later on you can take the reference ID and query your DB for full/concrete information you need.
Note that Metadata is a dictionary type.

Related

Can you query the DB inside a validate_doc_update function?

I am using validate_doc_update functions to do basic validation on the object to be stored. This is great to ensure that certain fields are present for example. But is there a way to do a validation based on a query from within the validate_doc_update function? For example, I want people to be able to sign up to bring items to a potluck. So each object will have fields for name, phone, and food (e.g. soda, salad, chips). So my validation function will check for each of those fields. No problem. But I also want to make sure that no more than two people sign up for the same food (not just a basic unique constraint). So if a new object with food value "chips" is being validated, and there are already 2 objects with food value "chips" in the DB, the validation should fail. Is there a way to do this with validation docs?
There is no facility to run a query in validate_doc_update.
One way to solve this issue is to decouple food items from user documents; instead have a document that represents the potluck:
{
_id: "potluck",
chips: {
needed: 2,
providers: ["user_id_1"]
},
soda: {
needed: 5,
providers: ["user_id_2","user_id_3"]
}
}
Here it is quite easy to validate sign ups of items. This document exudes a lot of information e.g. the number of items needed for any item is always needed - providers.length. User id's link food items users have signed up to provide.
It would be easy to generate a potluck report using a view or two with this approach.

How to expose MongoDB documents primary keys in a REST API?

I am building a REST API with MongoDB + nodeJS. All the documents are stored and are using _id as the primary key. I've read here that we should not expose the _id and we should use another ID which is not incremental.
In the DB, a document is represented as:
{
_id: ObjectId("5d2399b83e9148db977859ea")
bookName: "My book"
}
For the following the endpoints, how should the documents be exposed?
GET /books
GET /books/{bookId}
Currently my API returns:
{
_id: "5d2399b83e9148db977859ea"
bookName: "My book"
}
but should it instead return something like:
{
id: "some-unique-id-generated-on-creation"
bookName: "My book"
}
Questions
Should I expose the _id so that one can make queries such as:
GET /books/5d2399b83e9148db977859ea
Should I use a UUID for my ID instead of ObjectId?
Should I keep the internal _id (but never expose it) and create another attribute id which would use UUID or another custom generated ID ?
Is it a good practice to work with _id in my backend or should I only make queries using my own custom ID? Example: find({ id: }) instead of find({ _id: })
To answer your questions.
You can expose _id so that authenticated users can make queries like GET, PUT and PATCH on that _id.
MongoDB has support that allows you to generate your own BSON ID and use it, instead of mongodb created it's own _id during the insert.
There is no need of duplicating logic, the main purpose of _id is to identify each document separately and having two id columns means you are storing redundant data, follow DRY (DO NOT REPEAT YOURSELF) principle wherever possible.
It's not a bad practice to work with _id in your backend.
Hope this helps!
Given you're using Mongoose, you can use 'virtuals', which are essentially fake fields that Mongoose creates. They're not stored in the DB, they just get populated at run time:
// Duplicate the ID field.
Schema.virtual('id').get(function(){
return this._id.toHexString();
});
// Ensure virtual fields are serialised.
Schema.set('toJSON', {
virtuals: true
});
Any time toJSON is called on the Model you create from this Schema, it will include an 'id' field that matches the _id field Mongo generates. Likewise you can set the behaviour for toObject in the same way.
You can refer the following docs:
1) https://mongoosejs.com/docs/api.html
2) toObject method
In my case, whether it's a security risk or not, but my _id is a concatenation of any of the fields in my Document that are semantically considered as keys, i.e. if i have First Name, Last Name, and Email as my identifier, and a fourth field such as Age as attribute, then _id would be concatenation of all these 3 fields. It would not be difficult to get and update such record as long as I have First Name, Last Name and email information available

Rally-Node REST API return specific User Story or Defects

I'm reading the rally-node wiki and I don't get how to Read an Object. The part I don't get is the ref part.
How would I know the ref of the user story if I only know the title and the formatted ID (US5) of the story?
I know that after creating a user story I have a _ref that contains .../hierarchicalrequirement/121212121212 and by using that I can read the object, but is there another way of doing it? Since how would I know what my _ref is of a user story I created a long time ago?
Or is the best way to get user story from Rally is using restApi.query({})?
What I want to do is to return a specific user story, defect, etc from Rally with specific fetch data i.e. Formatted ID, Name, etc.
Thanks.
Your instincts are correct- ff you only know the FormattedID or Name you'll need to just query for it.
restApi.query({
type: 'hierarchicalrequirement', //the type to query
fetch: ['FormattedID', 'Name', 'ScheduleState', 'Children'], //the fields to retrieve
query: queryUtils.where('FormattedID', '=', 'US5'), //formatted id filter
scope: {
workspace: '/workspace/1234' //specify to query entire workspace
}
}).then(); //process results

"Right" way to keep API db tables in sync

It's my first time creating an application solo (back-end, front-end, design) and I could use some guidance on my back-end.
Let's say there is a table of Users, Jobs, and Applications (Job Applications). Right now I have it structured like so:
UserSchema {
// other attributes
_id: String,
application_ids: [String] // array of String id's
}
JobSchema {
// other attributes
_id: String,
application_ids: [String]
}
ApplicationSchema {
// other attributes
_id: String,
applicant_id: String, // the _id of a User
job_id: String // the _id of a Job
}
My current plan is like when a new Application is created (via POST /api/applications where I send the User's _id and Job's _id) I would then set the Application's applicant_id to the User's _id and then update the User's application_ids array as well as the Job's application_ids array.
Question: Am I going about this in a reasonable manner or am I touching too many tables for one POST request? There are other tables/schemas in my application that will follow a similar relationship structure. Then there's the matter of deleting Applications and then having to update application_ids again and etc, etc but that's another matter.
Note: I am using Express.js and Mongoose.js, if that helps
No, you shouldn't do it this way. By storing the ID of the user and job in the application, you can use a query to get all the applications by user or all applications for a given job. No need to touch both.
If you really want to have the relationship on both sides, at least set it up as an ObjectId and use the "ref" declaration. Check out the populate docs in the mongoose docs.

mongo: updating a document by id

OK this should be fairly simple so I think I may be doing a thinking mistake.
I have an existing document. I serve it to the client, together with its ObjectId. The client modifies, and wants to update the document. So it comes with the id - looks to me a good choice to identify which document I want to update (?).
But I get an error:
[MongoError: Mod on _id not allowed]
This is the code which updates (via HTTP PUT):
id = req.body._id
Item.update({'_id': id }, req.body, (err) ->
So you need to remove the _id key from the "update" object you send. _.omit can facilitate this.
Item.update {_id: req.body._id}, _.omit(req.body, '_id'), (err) ->
Aside: I see people code like this often. Taking input from the browser and just shoving it into your database is a terrible idea from a data integrity and security perspective. Just like most businesses don't just leave their accounting ledgers out on the counter with a pen and ask the customers to write in there unsupervised. Consider enforcing your data schema, authorization, and some validations.

Resources