Pode icon indicating copy to clipboard operation
Pode copied to clipboard

OpenAPI 3.0.3 and 3.1 full support

Open mdaneri opened this issue 1 year ago • 45 comments

Description of the Change

Revamped OpenAPI implementation

New Features

  • #1193
  • #1203
  • #1205
  • #1209
  • #1190
  • #1160
  • #1157
  • #1201
  • #1213
  • #1206
  • #1204
  • #1212
  • #1202
  • #1168
  • #1212
  • #1218
  • #1219
  • #1157
  • #1211
  • #1220
  • #1164
  • #1210
  • #1215
  • #1214
  • #1216
  • #1224
  • #1225
  • #1226
  • #1229
  • OpenApi Oauth and multiple authentications
  • Improved Cors support with AutoMethods and AutoHeader
  • #1088
  • #1004
  • #967

Sample

  • #1223

Documentation

  • #1221
  • #1222

The following new functions have been added:

New CmdLets

  • OpenAPI
    • Test-PodeOAJsonSchemaCompliance
    • Test-PodeOADefinition
    • Test-PodeOADefinitionTag
    • Select-PodeOADefinition
    • Add-PodeOAInfo
    • Add-PodeOAExternalDoc
    • New-PodeOAExternalDoc
    • Add-PodeOATag
    • Merge-PodeOAProperty
    • Add-PodeOAServerEndpoint
    • New-PodeOAExample
    • New-PodeOAEncodingObject
    • New-PodeOAResponse
    • Add-PodeOACallBack
    • New-PodeOAResponseLink
    • New-PodeOAContentMediaType
    • New-PodeOAMultiTypeProperty
    • Add-PodeOAExternalRoute
    • New-PodeOAServerEndpoint
    • Add-PodeOAWebhook
  • OpenAPI Components
    • Add-PodeComponentGroup
    • Add-PodeOAComponentHeader
    • Add-PodeOAComponentExample
    • Add-PodeOAComponentParameter
    • Add-PodeOAComponentResponseLink
    • Add-PodeOAComponentCallBack
    • Add-PodeOAComponentPathItem
    • Add-PodeOAWebhook
    • Test-PodeOAComponent
  • OpenAPI Definitions
    • Test-PodeOADefinition
    • Select-PodeOADefinition
  • Response Helper
    • Write-PodeYamlResponse
  • Utility
    • ConvertFrom-PodeXML

Related Issue

  • #1128
  • #1131
  • #1182
  • #1154
  • #1177
  • #1138
  • #1198
  • #1088

mdaneri avatar Aug 31 '23 04:08 mdaneri

new cmd-lets 'Test-PodeOARequestSchema', 'New-PodeOAExtraInfo', 'Add-PodeOAExternalDoc', 'Add-PodeOATag', 'Add-PodeOAComponentHeaderSchema'

mdaneri avatar Aug 31 '23 15:08 mdaneri

My visual studio code is doing it automatically. I tried to change the editor setting without luck. What editor are you using?

mdaneri avatar Sep 11 '23 23:09 mdaneri

Hi @mdaneri,

The editor I'm using is VS Code.

Just to let you know, I've not forgotten about this PR! I've been doing some work around Authentication which I'm just put some finishing touches to - the changes do slightly touch the OpenAPI files but only for minor tweaks, I'm not expecting them to cause any major issues here (famous last words!), but some files could conflict.

Badgerati avatar Oct 08 '23 16:10 Badgerati

Please submit your changes I can merge them on my side

mdaneri avatar Oct 08 '23 19:10 mdaneri

To help with the formatting, and to reduce the changes in files (going through just Helpers.ps1 alone is giving me a headache with all the { changes 😂), I've opened #1169 to enforce workspace PowerShell code formatting in VSCode - and to reformat the main /src files too.

Because of the way the auto-formatting works, it will actually more closely match the auto-formatting that's occurring on your side, with bracers on the same line as functions, and padding out hashtables, etc.

I've been meaning to do this for a while to help others as well. I'll aim to do this tomorrow.

Badgerati avatar Oct 16 '23 22:10 Badgerati

Hi @mdaneri,

I've merged #1169. Something I just spotted is that you've added .vscode/settings.json to the .gitignore, this'll need removing as the auto code-formatting is done using this file. Might be worth reviewing what changes you have in this file to make sure they don't conflict with Pode's now defined workspace settings.

Badgerati avatar Oct 17 '23 20:10 Badgerati

My bad was not my intention to have .gitignore replicated Let me delete it from my repo


Sent from Workspace ONE Boxerhttps://whatisworkspaceone.com/boxer On October 17, 2023 at 1:41:45 PM PDT, Matthew Kelly @.***> wrote: !! External Email

Hi @mdanerihttps://github.com/mdaneri,

I've merged #1169https://github.com/Badgerati/Pode/issues/1169. Something I just spotted is that you've added .vscode/settings.json to the .gitignore, this'll need removing as the auto code-formatting is done using this file. Might be worth reviewing what changes you have in this file to make sure they don't conflict with Pode's now defined workspace settings.

— Reply to this email directly, view it on GitHubhttps://github.com/Badgerati/Pode/pull/1136#issuecomment-1767141375, or unsubscribehttps://github.com/notifications/unsubscribe-auth/AEC2V2KYX3H5GC5DWRQ6KLTX73UQNAVCNFSM6AAAAAA4FPFY4OVHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMYTONRXGE2DCMZXGU. You are receiving this because you were mentioned.Message ID: @.***>

!! External Email: This email originated from outside of the organization. Do not click links or open attachments unless you recognize the sender.

mdaneri avatar Oct 17 '23 21:10 mdaneri

I had some issues with powershell-yaml on Linux. I was thinking of making a fork of the project, making it more Linux-friendly, and updating the .NET library to v6 and v7. But in the end, it was much easier to create a new cmdlet using an old sample. That is the reason I created one ad-hoc. To support OpenApi, what I wrote is good enough and simple to maintain. Ultimately, you are dealing only with arrays/hashtables of string, number, and boolean. There is no complex type we have to deal with.

I can try to work with the Pode YAML module again, but you have to publish a working version. The one that is available on Powershell Gallery needs to be fixed. It's complaining regarding a -now parameter that doesn't exist.

mdaneri avatar Oct 18 '23 22:10 mdaneri

I just tried to use powershell-yaml and this is the error Get-Serializer: Unable to find type [StringQuotingEmitter].

I modified helper.ps1 ConvertTo-PodeYamlInternal to use powershell-yaml

function ConvertTo-PodeYamlInternal {

    [OutputType('System.String')]

    [CmdletBinding()]
    param (
        [parameter(Position = 0, Mandatory = $true, ValueFromPipeline = $true)]
        [AllowNull()]
        $InputObject,
        [parameter(Position = 1, Mandatory = $false, ValueFromPipeline = $false)]
        [int]$Depth = 20,
        [parameter(Position = 2, Mandatory = $false, ValueFromPipeline = $false)]
        [int]$NestingLevel = 0,
        [parameter(Position = 3, Mandatory = $false, ValueFromPipeline = $false)]
        [int]$XMLAsInnerXML = 0,
        [parameter(Position = 4, Mandatory = $false, ValueFromPipeline = $false)]
        [switch] $NoNewLine
    )
    if ((Test-PodeModuleInstalled -Name 'powershell-yaml')) {
        $res = ConvertTo-Yaml -Data $InputObject
        return $res
    }

Now I'm trying with PSYaml

mdaneri avatar Oct 19 '23 00:10 mdaneri

PSYaml works fine I'm modifying the code to check if PSYaml is available will be used instead of the internal converter.

mdaneri avatar Oct 19 '23 01:10 mdaneri

Which version of powershell-yaml were you using? According to https://github.com/cloudbase/powershell-yaml/pull/97 that serializer error should be fixed in 0.4.7 🤔

Agreed that Pode.Yaml needs fixing, I have also considered bringing the YAML functionality directly into Pode. If you want to make this logic work with PSYaml, I'll go through and port over I'll the YAML logic from Pode.Yaml once merged - with some extra logic/flags.

Badgerati avatar Oct 21 '23 11:10 Badgerati

Good question I'm using the one available on the PowerShell gallery. Anyway, have you checked my last changes regarding Yaml support? Practically, I removed the public coverto-PodeYaml and included the logic to use a different yaml library if available. By doing that, I can generate the open API YAML version, but no one externally can use it.

mdaneri avatar Oct 21 '23 18:10 mdaneri

Another thing I have done lately is to enable the Open API properties definition to be piped. This makes the code much cleaner and more powershell. I still have to add the logic for objects. Because an object can be a property or a properties container, and so far, I can only pipe an object as simple property

mdaneri avatar Oct 21 '23 18:10 mdaneri

I’m going to try with 5.1. I forgot that Microsoft still supports it 😊 The Yaml is not on the OpenApi file but on private/helper.ps1

mdaneri avatar Oct 21 '23 23:10 mdaneri

I think to have addressed all your concerns. let me know

mdaneri avatar Oct 22 '23 05:10 mdaneri

I have a question regarding my last improvement New-PodeOA......Property and the pipeline.

 New-PodeOAIntProperty -Name 'id'-Format Int64 -ReadOnly -Example 10 |
            New-PodeOAIntProperty -Name 'petId' -Format Int64 -Example 198772 | 
            New-PodeOASchemaProperty -Name 'Address' -ComponentSchema 'Address' |
            New-PodeOAObjectProperty -Name 'Order' -Xml @{'name' = 'order' } -PropertiesFromPipeline7 |
            New-PodeOAStringProperty -Name 'shipDate' -Format Date-Time |
            New-PodeOAStringProperty -Name 'status' -Description 'Order Status' -Example 'approved' -Enum @('placed', 'approved', 'delivered') |
            New-PodeOABoolProperty -Name 'complete' |
            New-PodeOASchemaProperty -Name 'Address' -ComponentSchema 'Address' |
            New-PodeOAObjectProperty -Name 'Order' -Xml @{'name' = 'order' } -PropertiesFromPipeline

this creates an Object from the pipeline. still there is the old -properties parameter.

The question is regarding -PropertiesFromPipeline switch. Do you think this should be the default behavior? I mean by default New-PodeOAObjectProperty behave like any other PodeOAProperty and can be concatenated.

like on this example:

New-PodeOAStringProperty -Name 'lastName' -Example 'James' | 
 New-PodeOAObjectProperty -Name 'User' -Xml @{'name' = 'user' } -Properties  (
            New-PodeOAIntProperty -Name 'id'-Format Int64 -Example 1 -ReadOnly |
                New-PodeOAStringProperty -Name 'username' -Example 'theUser' -Required )| 
                  New-PodeOAStringProperty -Name 'username' -Example 'theUser' -Required |
                New-PodeOAStringProperty -Name 'firstName' -Example 'John' |
                New-PodeOAStringProperty -Name 'lastName' -Example 'James' | 
                New-PodeOAObjectProperty -Name 'test' -PropertiesFromPipeline

What do you think ?

mdaneri avatar Oct 22 '23 16:10 mdaneri

regarding the test-json and 5.1 compatibility. I'm going to put a version check and if PowerShell is 5.1 return true without doing anything.

Still, I've to work on the Test-PodeOARequestSchema because at the moment oneOf, allOf and anyOff are not supported.

mdaneri avatar Oct 22 '23 19:10 mdaneri

@mdaneri, that should be everything currently committed reviewed! :)

Something I spotted just was the docs haven't bee updated currently - are you just waiting until you've got the work done?

Badgerati avatar Oct 22 '23 22:10 Badgerati

I have a question regarding my last improvement New-PodeOA......Property and the pipeline.

 New-PodeOAIntProperty -Name 'id'-Format Int64 -ReadOnly -Example 10 |
            New-PodeOAIntProperty -Name 'petId' -Format Int64 -Example 198772 | 
            New-PodeOASchemaProperty -Name 'Address' -ComponentSchema 'Address' |
            New-PodeOAObjectProperty -Name 'Order' -Xml @{'name' = 'order' } -PropertiesFromPipeline7 |
            New-PodeOAStringProperty -Name 'shipDate' -Format Date-Time |
            New-PodeOAStringProperty -Name 'status' -Description 'Order Status' -Example 'approved' -Enum @('placed', 'approved', 'delivered') |
            New-PodeOABoolProperty -Name 'complete' |
            New-PodeOASchemaProperty -Name 'Address' -ComponentSchema 'Address' |
            New-PodeOAObjectProperty -Name 'Order' -Xml @{'name' = 'order' } -PropertiesFromPipeline

this creates an Object from the pipeline. still there is the old -properties parameter.

The question is regarding -PropertiesFromPipeline switch. Do you think this should be the default behavior? I mean by default New-PodeOAObjectProperty behave like any other PodeOAProperty and can be concatenated.

like on this example:

New-PodeOAStringProperty -Name 'lastName' -Example 'James' | 
 New-PodeOAObjectProperty -Name 'User' -Xml @{'name' = 'user' } -Properties  (
            New-PodeOAIntProperty -Name 'id'-Format Int64 -Example 1 -ReadOnly |
                New-PodeOAStringProperty -Name 'username' -Example 'theUser' -Required )| 
                  New-PodeOAStringProperty -Name 'username' -Example 'theUser' -Required |
                New-PodeOAStringProperty -Name 'firstName' -Example 'John' |
                New-PodeOAStringProperty -Name 'lastName' -Example 'James' | 
                New-PodeOAObjectProperty -Name 'test' -PropertiesFromPipeline

What do you think ?

If I understand what you're asking, then because the -Properties currently come from the parameter itself, the -PropertiesFromPipeline switch is the better approach. Otherwise it'd be a breaking change for people to have to re-jig their code to support the new format.

Ooorr, if -Properties is null/empty, then default to from the pipeline instead - that could work 🤔

Badgerati avatar Oct 22 '23 22:10 Badgerati

Now I'm able to pass invoke-build test I have only one issue with your request to remove foreach-object I tried but doesn't work. if you can give a look to the code

Thanks

mdaneri avatar Oct 26 '23 00:10 mdaneri

I solved the issue. Soon I’m going to post the final version after I verified a possible issue

mdaneri avatar Oct 26 '23 13:10 mdaneri

How much more is there to complete here, looking at all the OpenAPI issues/features raised? The documentation (https://github.com/Badgerati/Pode/blob/develop/docs/Tutorials/OpenAPI.md) also still needs going over as well 😃

I got an email for a comment about an issue with PS7.3.9. I can't find it here, so just wondering if that was still an issue? I saw the release yesterday, and the release notes looked all right, so surprised to see it might cause a problem. I'm going to upgrade to 7.3.9 myself tonight and test Pode, as the containers will use that version when I release 2.9.0 this weekend. If it is still a problem, mind raising a bug issue for it, and I'll test later?

Badgerati avatar Oct 27 '23 08:10 Badgerati

Yes I did. I upgraded my window, visual studio pro and powershell and for some arcane reason Pode stopped to work I rebuilt the DLL and everything was fine.

mdaneri avatar Oct 27 '23 13:10 mdaneri

Any additional feature is a plus I think we can stop here for 2.9.0

There are so many important improvements on 2.9 other than OpenApi that cannot wait .

Additional OA features like 3.1.0 support can go in 2.9.1 because are minor

mdaneri avatar Oct 27 '23 13:10 mdaneri

I've just tested 7.3.9 myself, and all looks good too :)

In terms of the documentation, everything here should be backwards compatible (bar the comment above). Have you reviewed the current docs to make sure nothing needs to be updated, and that any new functionality to be added to the docs could be left to a 2.9.1 or 2.10.0?

Badgerati avatar Oct 27 '23 21:10 Badgerati

I found two bugs that I have to fix. One is related to CORS. A bug has been open The other is related to schema validation. When allOf is part of the schema my implementation doesn't work as expected. I’m doing something wrong when I replace allOf with the correct properties

mdaneri avatar Oct 27 '23 21:10 mdaneri

I submitted everything, and I was able to pass the test. For the next minor release I’m going to implement the OA test. So far there is nothing to validate anything OpenApi related

Another thing I have to add is the json validation for anyOf and oneOf. Are not very easy to implement. Test-json is not capable of dealing with OpenApi definitions

mdaneri avatar Oct 29 '23 18:10 mdaneri

Please take a look at what I just added regarding the security headers. I think it's very cool (I wrote it 😀) and is making my life easier with CORS

mdaneri avatar Oct 29 '23 18:10 mdaneri

Oops 😣

mdaneri avatar Oct 30 '23 21:10 mdaneri

@mdaneri, besides the above issue, is that everything for this PR committed and ready for merging?

Badgerati avatar Oct 30 '23 22:10 Badgerati