Gi60s / openapi-enforcer

Apache License 2.0
94 stars 23 forks source link

How to validate the response that uses format: date-time? #158

Closed irobson closed 1 year ago

irobson commented 1 year ago

I'm trying to understand the documentation but it doens't give too much information about this specific piece, so, what I'm doing:

const openapi = await Enforcer('./path/to/openapi.yml')

  const [ req ] = openapi.request({
    method: 'GET',
    path: '/tasks/1',
  })

  const responseData = axiosClient.execute();
  const [ res, error ] = req.response(200, responseData, ..)

I'm getting something like startDate: expected a valid date object, because responseData is returning:

{
   startDate: "2023-07-24T14:57:59.041Z"
}

and in my schema definition, I have this one as

   startDate:
      type: string
      format: date-time

but I don't know how to "deserialize" the responseData to have it properly validated in the req.response method. Is it expected?

Gi60s commented 1 year ago

Hello @irobson. Thanks for the the question.

Correct me if I'm misunderstanding the question, but it sounds like the const responseData = axiosClient.execute(); is returning an object that has the startDate field set to a string value. The req.response function is looking to convert a date into a string, so what is happening here is that it's receiving that startDate field and complaining that it isn't a Date object.

I think the easiest solution in this case would be to convert that property to a date prior to calling the req.response function. In your case that can be done using responseData.startDate = new Date(responseData.startDate).

I hope that helps. Let me know either way.

irobson commented 1 year ago

@Gi60s it will be a bit costly because I created a framework to call a lot of endpoints, can't handle that specifically for one or another field, dates in JSON are always string. It limits a lot, because in many kinda of apps, the application will just delegate responses to your library, without any control on it. I thought that could be a way to do that thorugh the enforcer/deserialize it automatically. Thanks for your answer anyway.

Gi60s commented 1 year ago

Another possible solution is to use a schema hook. These can intercept and alter behavior for serialization/deserialization and validation. You could set up a hook that checks if a string looks like a date-time string and the schema has a format of date-time that it should assume the date is valid and skip validation.

Here is a regular expression you could use to quickly validate that the format of the string is a date-time format: ^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}(?:\.\d+)?(?:Z|[+-]\d{2}:?\d{2})$