data-api-client
data-api-client copied to clipboard
Bug regarding dates
Hello,
First of all, thanks for this library. It is so annoying having to use AWS SDK for this...
Anyway, I detected what I think is a bug.
My project uses Amplify, AppSync (GraphQL), Lambdas and Aurora Serverless.
One of the types I have in my graphql schema is this one:
type User {
userId: ID!
dob: AWSDate!
….
}
NOTE: dob is date of birth, so I only care about the date, not about time.
The SQL command I have in my lambda function is something like:
SELECT userId, dob …..FROM User WHERE userId='$id'
When using AWS framework
var dbResponse = await RDS.executeStatement(params).promise();
I receive something like this:
{
"numberOfRecordsUpdated": 0,
"records": [
[
{
"stringValue": "Ricardo"
},
{
"stringValue": "1956-03-12"
}
]
]
}
And everything works fine.
However, if I use this library in my lambda function: let dbResponse = await dataApiClient.query('SELECT userId, dob FROM User WHERE userId =:userId;', { userId: userId }); Then I receive this:
{
"records": [
{
"userId": "01B452F74BC941E58642766EE9D2C473",
"dob": "1977-09-19T00:00:00.000Z",
....
},
And because of that, graphql mapping is failing with this error:
▿ Can't serialize value (/getUsersForGame[0]/user/dob) : Unable to serialize `1977-09-19T00:00:00.000Z` as a valid date.
▿ object : 3 elements
▿ 0 : 2 elements
- key : "message"
- value : Can't serialize value (/getUsersForGame[0]/user/dob) : Unable to serialize `1977-09-19T00:00:00.000Z` as a valid date.
▿ 1 : 2 elements
- key : "path"
▿ value : 4 elements
- 0 : getUsersForGame
- 1 : 0
- 2 : user
- 3 : dob
▿ 2 : 2 elements
- key : "locations"
- value : <null>
BTW, when I use AWS console and I use the query editor, I also see "1956-03-12", without time.
About my RDS database, the type is this one:
dob date NOT NULL
So, for some reason, seems this library is not processing the date type properly. Do you know what's going on? Thanks a lot.
EDIT:
I found a workaround. Not ideal, but better than having to use AWS framework:
SELECT DATE_FORMAT(dob, GET_FORMAT(DATE,'ISO')) as dob from User;
RDS Data API returning a string is correct/expected behavior. I don't think it has anything to do with the data-api-client library. So you'll have to transform dates yourself.
I have the very same problem with Postgres returning dates in useless formats:
"2020-11-03 17:30:16.046186+00"
So I wrote a function to transform dates and other stuff that the Data API returns:
const pgDateRx = '^\\d{4}-\\d{2}-\\d{2} \\d{2}:\\d{2}:\\d{2}\\.\\d+';
const jsonRx = '^\\[?{(?:\\s*"?\\w+":\\s*"?[\\S\\s]+"?,?\\s*)*}\\]?$';
export function transformData(obj, patterns) {
if (Array.isArray(obj)) {
return obj.map(o => transformData(o, patterns));
}
const newObj = { ...obj };
for (const key in obj) {
for (const pat in patterns) {
if (new RegExp(pat).test(obj[key])) {
newObj[key] = patterns[pat](obj[key]);
}
}
}
return newObj;
}
export const standardTransform = obj =>
transformData(obj, {
[jsonRx]: value => JSON.parse(value),
[pgDateRx]: value => new Date(value + 'Z').toISOString(),
});