private static void ReadServers(ApiDefinition apiDefinition, Uri sourceUri, OpenApiDocument openApiDocument) { foreach (OpenApiServer server in openApiDocument.Servers) { string url = server.Url?.EnsureTrailingSlash(); string description = server.Description; if (url is null) { continue; } if (Uri.IsWellFormedUriString(url, UriKind.Absolute) && Uri.TryCreate(url, UriKind.Absolute, out Uri absoluteServerUri)) { apiDefinition.BaseAddresses.Add(new ApiDefinition.Server() { Url = absoluteServerUri, Description = description }); } else if (Uri.TryCreate(sourceUri, url, out Uri relativeServerUri)) { apiDefinition.BaseAddresses.Add(new ApiDefinition.Server() { Url = relativeServerUri, Description = description }); } } }
public ApiDefinition Read(JObject document, Uri swaggerUri) { foreach (IApiDefinitionReader reader in _readers) { if (reader.CanHandle(document)) { ApiDefinition result = reader.ReadDefinition(document, swaggerUri); return(result); } } return(null); }
public ApiDefinition ReadDefinition(string document, Uri sourceUri) { OpenApiStringReader reader = new(); OpenApiDocument openApiDocument = reader.Read(document, out _); ApiDefinition apiDefinition = new ApiDefinition(); ReadServers(apiDefinition, sourceUri, openApiDocument); IList <EndpointMetadata> metadata = ReadPaths(openApiDocument); apiDefinition.DirectoryStructure = BuildDirectoryStructure(metadata); return(apiDefinition); }
public ApiDefinitionParseResult ReadDefinition(string document, Uri?sourceUri) { OpenApiStringReader reader = new(); OpenApiDocument openApiDocument = reader.Read(document, out OpenApiDiagnostic diagnostic); ApiDefinition apiDefinition = new ApiDefinition(); ReadServers(apiDefinition, sourceUri, openApiDocument); IList <EndpointMetadata> metadata = ReadPaths(openApiDocument); apiDefinition.DirectoryStructure = BuildDirectoryStructure(metadata); return(new ApiDefinitionParseResult(true, apiDefinition, diagnostic.Errors.Select(e => e.ToString()))); }
// Based on latest spec at https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.0.2.md public ApiDefinition ReadDefinition(JObject document, Uri sourceUri) { document = document ?? throw new ArgumentNullException(nameof(document)); ApiDefinition apiDefinition = new ApiDefinition(); List <EndpointMetadata> metadata = new List <EndpointMetadata>(); if (document["servers"] is JArray serverArray) { foreach (JObject server in serverArray) { string url = server["url"]?.Value <string>()?.EnsureTrailingSlash(); string description = server["description"]?.Value <string>(); if (url is null) { continue; } if (Uri.IsWellFormedUriString(url, UriKind.Absolute) && Uri.TryCreate(url, UriKind.Absolute, out Uri absoluteServerUri)) { apiDefinition.BaseAddresses.Add(new ApiDefinition.Server() { Url = absoluteServerUri, Description = description }); } else if (Uri.TryCreate(sourceUri, url, out Uri relativeServerUri)) { apiDefinition.BaseAddresses.Add(new ApiDefinition.Server() { Url = relativeServerUri, Description = description }); } } } if (document["paths"] is JObject paths) { foreach (JProperty path in paths.Properties()) { if (!(path.Value is JObject pathBody)) { continue; } Dictionary <string, IReadOnlyDictionary <string, IReadOnlyList <Parameter> > > requestMethods = new Dictionary <string, IReadOnlyDictionary <string, IReadOnlyList <Parameter> > >(StringComparer.OrdinalIgnoreCase); foreach (JProperty method in pathBody.Properties()) { // A path item has a fixed set of field names and we are only looking for the set of // field names that are for operation objects if (!_ValidOperationNames.Contains(method.Name)) { continue; } requestMethods[method.Name] = new Dictionary <string, IReadOnlyList <Parameter> >(StringComparer.OrdinalIgnoreCase); List <Parameter> parameters = new List <Parameter>(); if (method.Value is JObject methodBody) { if (methodBody["parameters"] is JArray parametersArray) { foreach (JObject parameterObj in parametersArray.OfType <JObject>()) { Parameter p = parameterObj.ToObject <Parameter>(); p.Location = parameterObj["in"]?.ToString(); if (!(parameterObj["schema"] is JObject schemaObject)) { schemaObject = null; } p.Schema = schemaObject?.ToObject <Schema>() ?? parameterObj.ToObject <Schema>(); parameters.Add(p); } } if (methodBody["requestBody"] is JObject bodyObject) { if (!(bodyObject["content"] is JObject contentTypeLookup)) { continue; } foreach (JProperty contentTypeEntry in contentTypeLookup.Properties()) { List <Parameter> parametersByContentType = new List <Parameter>(parameters); Parameter p = new Parameter(); p.Location = "body"; p.IsRequired = bodyObject["required"]?.ToObject <bool>() ?? false; if (!(contentTypeEntry.Value is JObject contentTypeObject) || !(contentTypeObject["schema"] is JObject schemaObject)) { schemaObject = null; } p.Schema = schemaObject?.ToObject <Schema>() ?? bodyObject.ToObject <Schema>(); parametersByContentType.Add(p); Dictionary <string, IReadOnlyList <Parameter> > bucketByMethod; if (!requestMethods.TryGetValue(method.Name, out IReadOnlyDictionary <string, IReadOnlyList <Parameter> > bucketByMethodRaw)) { requestMethods[method.Name] = bucketByMethodRaw = new Dictionary <string, IReadOnlyList <Parameter> >(StringComparer.OrdinalIgnoreCase) { { "", parametersByContentType } }; } bucketByMethod = (Dictionary <string, IReadOnlyList <Parameter> >)bucketByMethodRaw; bucketByMethod[contentTypeEntry.Name] = parametersByContentType; } } } } metadata.Add(new EndpointMetadata(path.Name, requestMethods)); } } DirectoryStructure d = new DirectoryStructure(null); foreach (EndpointMetadata entry in metadata) { ApiDefinitionReader.FillDirectoryInfo(d, entry); } apiDefinition.DirectoryStructure = d; return(apiDefinition); }
public ApiDefinition ReadDefinition(JObject document, Uri sourceUri) { document = document ?? throw new ArgumentNullException(nameof(document)); ApiDefinition apiDefinition = new ApiDefinition(); List <EndpointMetadata> metadata = new List <EndpointMetadata>(); string basePath = document["basePath"]?.Value <string>()?.EnsureTrailingSlash(); if (!string.IsNullOrWhiteSpace(basePath)) { if (Uri.TryCreate(basePath, UriKind.Absolute, out Uri serverUri)) { sourceUri = sourceUri ?? throw new ArgumentNullException(nameof(sourceUri)); apiDefinition.BaseAddresses.Add(new ApiDefinition.Server() { Url = serverUri, Description = $"Swagger v1 basePath from {sourceUri.ToString()}" }); } } if (!(document["consumes"] is JArray globalConsumes)) { globalConsumes = new JArray(); } if (document["apis"] is JArray jArray) { foreach (JObject obj in jArray) { string path = obj["path"]?.ToString(); if (path is null) { continue; } Dictionary <string, IReadOnlyDictionary <string, IReadOnlyList <Parameter> > > requestMethods = new Dictionary <string, IReadOnlyDictionary <string, IReadOnlyList <Parameter> > >(StringComparer.Ordinal); if (obj["operations"] is JArray operations) { foreach (JObject operationObject in operations.OfType <JObject>()) { string method = operationObject["method"]?.ToString(); List <Parameter> parameters = new List <Parameter>(); if (operationObject["parameters"] is JArray parametersArray) { foreach (JObject parameterObj in parametersArray.OfType <JObject>()) { Parameter p = parameterObj.ToObject <Parameter>(); p.Location = parameterObj["paramType"]?.ToString(); p.IsRequired = parameterObj["required"]?.ToObject <bool>() ?? false; string type = parameterObj["type"]?.ToString(); if (type is null) { continue; } switch (type.ToUpperInvariant()) { case "INTEGER": case "NUMBER": case "STRING": case "BOOLEAN": p.Schema = new Schema { Type = type }; break; case "FILE": break; default: if (document["models"]?[type] is JObject schemaObject) { //TODO: Handle subtypes (https://github.com/OAI/OpenAPI-Specification/blob/master/versions/1.2.md#527-model-object) p.Schema = schemaObject.ToObject <Schema>(); } break; } parameters.Add(p); } } if (!(operationObject["consumes"] is JArray consumes)) { consumes = globalConsumes; } Dictionary <string, IReadOnlyList <Parameter> > parametersByContentType = new Dictionary <string, IReadOnlyList <Parameter> >(StringComparer.OrdinalIgnoreCase) { { "", parameters } }; foreach (JValue value in consumes.OfType <JValue>().Where(x => x.Type == JTokenType.String)) { parametersByContentType[value.ToString()] = parameters; } if (method != null) { requestMethods[method] = parametersByContentType; } } } metadata.Add(new EndpointMetadata(path, requestMethods)); } } DirectoryStructure d = new DirectoryStructure(null); foreach (EndpointMetadata entry in metadata) { ApiDefinitionReader.FillDirectoryInfo(d, entry); } apiDefinition.DirectoryStructure = d; return(apiDefinition); }
public ApiDefinition ReadDefinition(JObject document, Uri sourceUri) { ApiDefinition apiDefinition = new ApiDefinition(); List <EndpointMetadata> metadata = new List <EndpointMetadata>(); if (!(document["consumes"] is JArray globalConsumes)) { globalConsumes = new JArray(); } string host = document["host"]?.Value <string>(); string basePath = document["basePath"]?.Value <string>()?.EnsureTrailingSlash(); IEnumerable <string> schemes = document["schemes"]?.Values <string>(); if (!string.IsNullOrWhiteSpace(host)) { if (schemes == null) { schemes = new[] { sourceUri.Scheme }; } foreach (string scheme in schemes) { if (Uri.TryCreate($"{scheme}://{host}{basePath}", UriKind.Absolute, out Uri serverUri)) { apiDefinition.BaseAddresses.Add(new ApiDefinition.Server() { Url = serverUri, Description = $"Swagger v2 combined scheme, host and basePath from {sourceUri.ToString()}" }); } } } if (document["paths"] is JObject obj) { foreach (JProperty property in obj.Properties()) { if (!(property.Value is JObject requestMethodInfos)) { continue; } Dictionary <string, IReadOnlyDictionary <string, IReadOnlyList <Parameter> > > requestMethods = new Dictionary <string, IReadOnlyDictionary <string, IReadOnlyList <Parameter> > >(StringComparer.Ordinal); foreach (JProperty methodInfo in requestMethodInfos.Properties()) { List <Parameter> parameters = new List <Parameter>(); if (methodInfo.Value is JObject methodInfoDescription) { if (methodInfoDescription["parameters"] is JArray parametersArray) { foreach (JObject parameterObj in parametersArray.OfType <JObject>()) { //TODO: Resolve refs here Parameter p = parameterObj.ToObject <Parameter>(); p.Location = parameterObj["in"]?.ToString(); p.IsRequired = parameterObj["required"]?.ToObject <bool>() ?? false; if (!(parameterObj["schema"] is JObject schemaObject)) { schemaObject = null; } p.Schema = schemaObject?.ToObject <Schema>() ?? parameterObj.ToObject <Schema>(); parameters.Add(p); } } if (!(methodInfoDescription["consumes"] is JArray consumes)) { consumes = globalConsumes; } Dictionary <string, IReadOnlyList <Parameter> > parametersByContentType = new Dictionary <string, IReadOnlyList <Parameter> >(StringComparer.OrdinalIgnoreCase) { { "", parameters } }; foreach (JValue value in consumes.OfType <JValue>().Where(x => x.Type == JTokenType.String)) { parametersByContentType[value.ToString()] = parameters; } requestMethods[methodInfo.Name] = parametersByContentType; } } metadata.Add(new EndpointMetadata(property.Name, requestMethods)); } } DirectoryStructure d = new DirectoryStructure(null); foreach (EndpointMetadata entry in metadata) { ApiDefinitionReader.FillDirectoryInfo(d, entry); } apiDefinition.DirectoryStructure = d; return(apiDefinition); }