mattpolzin / OpenAPIKit

Codable Swift OpenAPI implementation.
MIT License
280 stars 35 forks source link

Add a `Validation` that checks all `operationId`s in `Link` objects are valid #236

Open mattpolzin opened 2 years ago

mattpolzin commented 2 years ago

Create a validation that operationIds in Link objects refer to Operation objects in the document that have the given ids. This should probably be an optional validation rather than a default one.

Note that you should make changes to both the OpenAPIKit30 and OpenAPIKit modules (the changes will be mostly if not entirely identical).

nexon commented 1 year ago

Hey @mattpolzin This is still necessary? I was thinking on giving a shot doing this one. If so, can you point me out how you were thinking on implement this?

mattpolzin commented 1 year ago

This isn't necessary to release v3.0.0, but I do still want to have this validation.

This will get implemented similarly to other optional validations (it won't get added to the default-on validations here: https://github.com/mattpolzin/OpenAPIKit/blob/release/3_0/Sources/OpenAPIKit/Validator/Validator.swift#L182..L195). It will still be exposed as a property on the Validation type, though, similar to e.g. https://github.com/mattpolzin/OpenAPIKit/blob/release/3_0/Sources/OpenAPIKit/Validator/Validation+Builtins.swift#L13..L27.

This particular validation may or may not be a bit tricky to implement now that I am thinking about it a bit more, simply because it must start with the context of a Link and then from there go and locate all operations to see if the Link's`operationId is found anywhere.

If you still want to take a crack at it, you would start with something like:

    public static var linkOperationsExist: Validation<OpenAPI.Link> {
        .init(
            description: "Links with operationIds have corresponding Operations",
            check: { context in
                guard case let .b(operationId) = context.subject.operation else {
                        // don't make assertions about Links that don't have operationIds
                        return true
                }
                // TODO: look at all Operations in the document and see if any have the
                //              given operationId
                let operationIdFound: Bool
                return operationIdFound
            }
        )
    }

The part left "TODO" above is the "interesting" part because PathItems have Operations and PathItems are found both within the Document and also in the Components (for OpenAPIKit, not for OpenAPIKit30). The context variable in the above code is a ValidationContext so it has a document property that you can use to access the Document and go from there.

Let me know if any of that needs to be clarified a bit more!