-
-
Notifications
You must be signed in to change notification settings - Fork 224
Add serDes
setting : serialize and deserialize
#506
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
…ize` request parameters or fields. It could resolve : cdimascio#353 cdimascio#465 cdimascio#288 cdimascio#246 Unit tests validate Date and MongoDb ObjectID. Developers have choice to : - only serialize response contents - also deserialize request strings to custom objects Frequent SerDes are defined in base.serdes.ts (date and date-time). Documentation updated with this setting
@cdimascio I added serDes: [{
OpenApiValidator.baseSerDes.dateTimeSerializeOnly,
OpenApiValidator.baseSerDes.dateSerializeOnly,
}], |
Sorry. Some tests fail. |
…erDes are defined (force DateTime and Date serialization).
@cdimascio It's good ! I fixed problems and, after reading you comments on #493, I added a default SerDes in order serialize date and date-time by default on response when no serDes is defined. All tests passed. I have a last question on
If you prefer the second solution, I can do it quickly. |
@pilerou Awesome! This is great. review nit:
i like the idea of making this the default behavior for serdes. would making this the default break existing users? finally,I'm sure many folks would benefit from your Mongo OjbectId (de)serializer. e.g. const pilerou = require('pilerou-serdes');
//...
serDes: [
pilerou.mongodb.objectid,
pilerou.mongodb.uuid,
// etc,
], |
…ause I answer with an ObjectID instead of Date and no toISOString function exists), a 500 error is thrown.
Hi @cdimascio (and happy new year ;)) First of all, I added a new test. If i answer with an object instead of Date and if this object hasn't a toISOString function, it fails and we get a 500 error. We can consider :
I think the best solution would be the third but I don't know how we could change AJV controls order.
Any idea ? For the MongoDB serdes project I created it : https://www.npmjs.com/package/mongo-serdes-js |
I just tested it on an API project with UUID :
components:
schema:
UUID:
type: string,
format: uuid,
pattern: '^[0-9a-f]{8}-[0-9a-f]{4}-[0-5][0-9a-f]{3}-[089ab][0-9a-f]{3}-[0-9a-f]{12}$'
app.post(`$rootUrl}/create`, async (req, res) => {
...
createdUser.uuid = MUUID.v4();
...
let responseContent = await myDb.Users.insert(createdUser);
// I return created object : in db, uuid field is Binary as UUID(..) object
res.json(responseContent.ops[0]);
// In response, serialize function is called and UUID is stringified
}
app.get(`${rootUrl}/uuid/:uuid`, async (req, res) => {
let user = await myDb.Users.findOne({ uuid });
res.json(user);
// in db, uuid field is Binary as UUID(..) object
// In response, serialize function is called and UUID is stringified
}); |
im struggling a bit with what the defaults should be
Why? if a request schema defines
Why? express will serialize the object by using its The unfortunate part here is that it seems a bit confusing as to what is and isn't enabled when you specify It brings me back to something I was considering earlier, that is, should we support only I must apologize for all the back and forth here. This is certainly complex, much more so that I initially thought. Some of the complexities we've discovered so far:
i like the (de)serialization feature, but i'm a bit hesitant as it seems it may lead to confusion and/or potentially more issue reports. let me know if you have thoughts/suggestions. |
Hi Carmine, I agree with you :
I therefore think that several cases should be foreseen: Case 1Developers want to add serialize and deserialize functions for Mongodb objects.
Case 2User doesn't want
Case 3The developer wishes to deserialize the dates in request and also his MongoDB types. With this solution :
I push you in few minutes an adaptation to review. |
…serDes settings. Custom settings can also override date and date-time formats in order to also deserialize date and/or date-time on requests
…serDes settings. Custom settings can also override date and date-time formats in order to also deserialize date and/or date-time on requests
Thanks @pilerou |
@pilerou i made some improvements to the schema preprocessor. assuming preprocessor related issues settle down. i'll get back to this |
@cdimascio Do not hesitate if you need help or if you want me to modify the PR fork. |
@pilerou thank you. as for this PR, one useful thing to do would be to rebase to mainline (or merge mainline to this branch). the recent performance (and correctness) changes impact the schema preprocessor which this of course depends on. hopefully there won't be conflicts. |
Hi @cdimascio |
@pilerou, the new preprocessor updaters have gone well, it seems reasonable to move forward with this
serdes: [
OpenApiValidator.serdes.date.serialize, // registers serializer only
OpenApiValidator.serdes.date.deserialize, // registers deserializer only
OpenApiValidator.serdes.date, // registers the serializer and deserializer
], It's possible that e.g date and/or serialize, serialize need to be methods rather than props. Feel free to explore. All in all, just want to ensure the interface is pleasant to use
thanks! |
Test OK Documentation is modified I also changed my https://github.com/pilerou/mongo-serdes-js with a 0.0.3 version which is compliant to the design : ```javascript serDes: [ OpenApiValidator.baseSerDes.date.serializer, OpenApiValidator.baseSerDes.dateTime, MongoSerDes.objectid, // this configuration if we want to deserialize objectid in request and serialize it in response MongoSerDes.uuid.serializer, // this configuration if we only want to serialize on response ], ```
@cdimascio I changed the design and the documentation. |
@pilerou yes. good idea. let's add them automatically. we should call that out in the doc as well |
@cdimascio it's ok. I added automation on unknownFormats population using serDes formats |
README.md
Outdated
{ | ||
format: 'mongo-objectid', | ||
serialize: (o) => o.toString(), | ||
} | ||
}], | ||
``` | ||
So, in conclusion, you can use `OpenApiValidator.baseSerDes.dateTime` if you can to serialize and deserialize dateTime. | ||
You can also use `OpenApiValidator.baseSerDes.dateTime.serializer` if you only want to serialize or `OpenApiValidator.baseSerDes.dateTime.deserializer` if you only want to deserialize. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Were you able to modify
OpenApiValidator.baseSerDes.dateTime.serializer
to OpenApiValidator.serdes.dateTime.serializer
Ultimately providing 3 options for the built-in formatters e.g.
OpenApiValidator.serdes.dateTime.serializer
OpenApiValidator.serdes.dateTime.deserializer
OpenApiValidator.serdes.dateTime
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
i.e. as noted in #506 (comment)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hi carmin
It's OK. I pushed a change with serdes instead of baseSerDes.
Hi @cdimascio |
@pilerou I'm looking to get this in. I'll spend some time this weekend to get it merged. I believe you covered everything. I'll review once more this week. To be sure Apologies for the long delay. |
@pilerou This change is now in! |
@pilerou i noticed this in the test output. it looks like an edge bug in The error appears when running the tests e.g. i see the following: POST /v1/users 400 2.068 ms - 79
✓ should POST throw error on invalid schema Date
functionNotExists
TypeError: d.toISOString is not a function
at Object.serialize (/Users/cdimasci/git/express-openapi-validator/src/framework/base.serdes.ts:16:19)
at Ajv.validate (/Users/cdimasci/git/express-openapi-validator/src/framework/ajv/index.ts:90:37)
at validate (eval at localCompile (/Users/cdimasci/git/express-openapi-validator/node_modules/ajv/lib/compile/index.js:120:26), <anonymous>:3:6690)
at ResponseValidator._validate (/Users/cdimasci/git/express-openapi-validator/src/middlewares/openapi.response.validator.ts:179:19)
at /Users/cdimasci/git/express-openapi-validator/src/middlewares/openapi.response.validator.ts:73:23
at ServerResponse.json_hook (/Users/cdimasci/git/express-openapi-validator/src/framework/modded.express.mung.ts:39:16) i see you have a test for this. that output is essentially consoled logged in the test. |
Hello @cdimascio |
And thank you for the merge. 👍 |
No problem. Thank you for your efforts! |
I had a look. express-openapi-validator/test/serdes.spec.ts Line 197 in 4c1354f
If we want to remove this error, we juste have to remove the test here : express-openapi-validator/test/serdes.spec.ts Line 304 in 4c1354f
|
* `serDes` setting allows to `serialize` response objects and `deserialize` request parameters or fields. It could resolve : #353 #465 #288 #246 Unit tests validate Date and MongoDb ObjectID. Developers have choice to : - only serialize response contents - also deserialize request strings to custom objects Frequent SerDes are defined in base.serdes.ts (date and date-time). Documentation updated with this setting * I don't know why there was a cloneDeep but it seems to be necessary in all cases. * Fix validation problems with oneOf and force default SerDes when no SerDes are defined (force DateTime and Date serialization). * Delete old code comments * New test : If I answer with an object which serialize fails (here because I answer with an ObjectID instead of Date and no toISOString function exists), a 500 error is thrown. * Add Date and date-time serialization by default in addition to other serDes settings. Custom settings can also override date and date-time formats in order to also deserialize date and/or date-time on requests * Add Date and date-time serialization by default in addition to other serDes settings. Custom settings can also override date and date-time formats in order to also deserialize date and/or date-time on requests * `serDes` option adaptation to be more user friendly Test OK Documentation is modified I also changed my https://github.com/pilerou/mongo-serdes-js with a 0.0.3 version which is compliant to the design : ```javascript serDes: [ OpenApiValidator.baseSerDes.date.serializer, OpenApiValidator.baseSerDes.dateTime, MongoSerDes.objectid, // this configuration if we want to deserialize objectid in request and serialize it in response MongoSerDes.uuid.serializer, // this configuration if we only want to serialize on response ], ``` * When we add custom formats in serDes, they are automatically added to unknownFormats * Rename OpenApiValidator.baseSerDes to OpenApiValidator.serdes
serDes
setting allows toserialize
response objects anddeserialize
request parameters or fields. It could resolve : #353 #465 #288 #246Unit tests validate Date and MongoDb ObjectID.
Developers have choice to :
Frequent SerDes are defined in base.serdes.ts (date and date-time).
Documentation updated with this setting