vapor/vapor

Having issue during validation of request

avinashamanjha251 opened this issue · 5 comments

I tried to validate the response for "userName" every time it's failed with error "Validation executor couldn't find any validations to run (broken Decoder?)". However I can see the data is coming from Controller to Vapor package and while creating BSONDecoder the value of validation is overwrite by other userInfo data which is declared in ExtendedJSONDecoder.

Screenshot 2023-07-29 at 4 16 20 PM
Screenshot 2023-07-29 at 4 16 43 PM
Screenshot 2023-07-29 at 4 17 28 PM

@avinashamanjha251 I saw that you closed this issue, but I wanted to double-check that you'd been able to solve this. From what I can see in the SwiftBSON code, the problem looks to me that the MongoDBVapor package hasn't been updated with support for the changes in the validation API I had to make a little while back. I've submitted a PR to them with the appropriate fix, but in the meantime, it is possible to work around the problem from your end as well if you're still having trouble.

@gwynne this issue is happening due the use of below setting

ContentConfiguration.global.use(encoder: ExtendedJSONEncoder(), for: .json)
ContentConfiguration.global.use(decoder: ExtendedJSONDecoder(), for: .json)

while calling configure func, after commenting above two Validation started working.
"public func configure(_ app: Application) async throws"

@avinashamanjha251 I have no idea when (or even if) the upstream repo will merge the PR I made that fixes the problem, but you can take advantage of the fix now by using the fork I made to do the PR from for now:

        // In your Package.swift:
        .package(url: "https://github.com/gwynne/mongodb-vapor.git", branch: "updated-content-coders-support")

Or alternatively, you can paste this code anywhere in your project (or just add it as a new file) to accomplish the same result:

import MongoDBVapor
import Vapor

extension ExtendedJSONEncoder {
     public func encode<E: Encodable>(_ encodable: E, to body: inout ByteBuffer, headers: inout HTTPHeaders, userInfo: [CodingUserInfoKey: Any]) throws {
         let encoder: ExtendedJSONEncoder
         if userInfo.isEmpty {
             encoder = self
         } else {
             encoder = ExtendedJSONEncoder()
             encoder.format = self.format
             encoder.userInfo = self.userInfo.merging(userInfo, uniquingKeysWith: { $1 })
         }
         headers.contentType = .json
         var buffer = try encoder.encodeBuffer(encodable)
         body.writeBuffer(&buffer)
     }
 }

 extension ExtendedJSONDecoder {
     public func decode<D: Decodable>(_: D.Type, from body: ByteBuffer, headers _: HTTPHeaders, userInfo: [CodingUserInfoKey: Any]) throws -> D {
         let decoder: ExtendedJSONDecoder
         if userInfo.isEmpty {
             decoder = self
         } else {
             decoder = ExtendedJSONDecoder()
             decoder.userInfo = self.userInfo.merging(userInfo, uniquingKeysWith: { $1 })
         }
         return try decoder.decode(D.self, from: body)
     }
 }

(This basically does the same thing the PR does; since the types in question are all public, you can just add the missing implementation directly.)

hi @gwynne thanks for the changes. Its working.

now we can close the ticket.