microsoft / OpenAPI.NET

The OpenAPI.NET SDK contains a useful object model for OpenAPI documents in .NET along with common serializers to extract raw OpenAPI JSON and YAML documents from the model.
MIT License
1.39k stars 231 forks source link

How to parse URL with placeholder? #250

Open selman92 opened 6 years ago

selman92 commented 6 years ago

I have a swagger document that starts like this:

{ "swagger": "2.0", "info": { "title": "Foo", "version": "1.3.0" }, "x-basePath": "{ipaddress}/bar/api/v0", "schemes": [ "https" ], }

As you can see the host part of the uri is a placeholder, does OpenAPI support this? I got an error when I tried to parse with OpenApiStreamReader

System.UriFormatException
  HResult=0x80131537
  Message=Invalid URI: The hostname could not be parsed.
  Source=System
darrelmiller commented 6 years ago

@selman92 Have you tried with the latest version of the library? I tried your example in the workbench tool and got the following:

openapi: 3.0.1
info:
  title: Foo
  version: 1.3.0
servers:
  - url: https://example.org//
paths: { }
x-basePath: '{ipaddress}/bar/api/v0'

There is an issue with the URL that gets generated in #/servers[0]/url however, I don't see how that would generate the error you are seeing.

selman92 commented 6 years ago

The version I use is v1.0.0-beta015, haven't tried with v1.0.0-beta17 yet. There is no url definition like this in the document, could that be the problem?

servers:
  - url: https://example.org//

In our project we are using AutoRest library and it parses the document without any problems. But since AutoRest doesn't support swagger 3.0 we want to switch OpenAPI.NET.

selman92 commented 6 years ago

This is the full stack trace of the error:

   at System.Uri.CreateThis(String uri, Boolean dontEscape, UriKind uriKind)
   at System.Uri..ctor(String uriString, UriKind uriKind)
   at Microsoft.OpenApi.Readers.V2.OpenApiV2Deserializer.<>c.<.cctor>b__68_150(OpenApiSecurityScheme o, ParseNode n)
   at Microsoft.OpenApi.Readers.ParseNodes.PropertyNode.ParseField[T](T parentInstance, IDictionary`2 fixedFields, IDictionary`2 patternFields)
   at Microsoft.OpenApi.Readers.V2.OpenApiV2Deserializer.LoadSecurityScheme(ParseNode node)
   at Microsoft.OpenApi.Readers.ParseNodes.MapNode.<>c__DisplayClass7_0`1.<CreateMapWithReference>b__0(KeyValuePair`2 n)
   at System.Linq.Enumerable.WhereSelectEnumerableIterator`2.MoveNext()
   at System.Linq.Enumerable.WhereEnumerableIterator`1.MoveNext()
   at System.Linq.Enumerable.ToDictionary[TSource,TKey,TElement](IEnumerable`1 source, Func`2 keySelector, Func`2 elementSelector, IEqualityComparer`1 comparer)
   at System.Linq.Enumerable.ToDictionary[TSource,TKey,TElement](IEnumerable`1 source, Func`2 keySelector, Func`2 elementSelector)
   at Microsoft.OpenApi.Readers.ParseNodes.MapNode.CreateMapWithReference[T](ReferenceType referenceType, Func`2 map)
   at Microsoft.OpenApi.Readers.V2.OpenApiV2Deserializer.<>c.<.cctor>b__68_16(OpenApiDocument o, ParseNode n)
   at Microsoft.OpenApi.Readers.ParseNodes.PropertyNode.ParseField[T](T parentInstance, IDictionary`2 fixedFields, IDictionary`2 patternFields)
   at Microsoft.OpenApi.Readers.V2.OpenApiV2Deserializer.ParseMap[T](MapNode mapNode, T domainObject, FixedFieldMap`1 fixedFieldMap, PatternFieldMap`1 patternFieldMap, List`1 requiredFields)
   at Microsoft.OpenApi.Readers.V2.OpenApiV2Deserializer.LoadOpenApi(RootNode rootNode)
   at Microsoft.OpenApi.Readers.V2.OpenApiV2VersionService.LoadDocument(RootNode rootNode)
   at Microsoft.OpenApi.Readers.ParsingContext.Parse(YamlDocument yamlDocument, OpenApiDiagnostic diagnostic)
   at Microsoft.OpenApi.Readers.OpenApiStreamReader.Read(Stream input, OpenApiDiagnostic& diagnostic)
   at ConsoleApp15.Program.Main(String[] args) in C:\foobar\Program.cs:line 17
immitev commented 2 years ago

I encountered a similar issue in the context of securityDefinitions element.

The OpenAPI JSON file uses a placeholder:

"authorizationUrl": "https://{yourwhitelabel}.acme.com/oauth/authorise",
"tokenUrl": "https://{yourwhitelabel}.acme.com/oauth/token",

And it seems like a good idea for the parser to be more forgiving and not throw error in this occasion. 🤔