Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
32 commits
Select commit Hold shift + click to select a range
bce3f59
adding support for query parameter in open api spec
Oct 3, 2023
324aa69
Merge branch 'main' into dev/abhishekkuma/open-api-documentor
abhishekkumams Oct 3, 2023
fd7635e
fix formatting
Oct 3, 2023
803b159
Merge branch 'dev/abhishekkuma/open-api-documentor' of https://github…
Oct 3, 2023
7b41ec7
Merge branch 'main' into dev/abhishekkuma/open-api-documentor
abhishekkumams Oct 4, 2023
c4c0fda
adding tests
Oct 4, 2023
65377f6
adding tests
Oct 4, 2023
77d7a8c
Merge branch 'main' into dev/abhishekkuma/open-api-documentor
abhishekkumams Oct 10, 2023
f8f13f2
fix formatting
Oct 10, 2023
663ae7d
Merge branch 'main' into dev/abhishekkuma/open-api-documentor
abhishekkumams Oct 11, 2023
9b93c14
fixing nits
Oct 13, 2023
d352410
fixing nits
Oct 13, 2023
81ba2d4
Merge branch 'main' into dev/abhishekkuma/open-api-documentor
abhishekkumams Oct 17, 2023
7121ae8
Merge branch 'main' into dev/abhishekkuma/open-api-documentor
abhishekkumams Oct 20, 2023
6a4e1c8
Merge branch 'main' into dev/abhishekkuma/open-api-documentor
abhishekkumams Oct 23, 2023
3b0042c
fixing nits
Oct 30, 2023
95c10bd
Merge branch 'main' into dev/abhishekkuma/open-api-documentor
abhishekkumams Nov 6, 2023
ca9981f
Update src/Core/Services/OpenAPI/OpenApiDocumentor.cs
abhishekkumams Nov 6, 2023
bfe9dc6
Update src/Core/Services/OpenAPI/OpenApiDocumentor.cs
abhishekkumams Nov 6, 2023
114ffcf
Update src/Service.Tests/OpenApiDocumentor/ParameterValidationTests.cs
abhishekkumams Nov 6, 2023
c157e87
Update src/Service.Tests/OpenApiDocumentor/ParameterValidationTests.cs
abhishekkumams Nov 6, 2023
b59923d
Update src/Service.Tests/OpenApiDocumentor/ParameterValidationTests.cs
abhishekkumams Nov 6, 2023
d1f839f
Update src/Service.Tests/OpenApiDocumentor/ParameterValidationTests.cs
abhishekkumams Nov 6, 2023
7ae2182
fixing nits
Nov 6, 2023
646cf24
Merge branch 'dev/abhishekkuma/open-api-documentor' of https://github…
Nov 6, 2023
4ab1f8f
fixing parameter description
Nov 7, 2023
3f36e31
Update src/Core/Services/OpenAPI/OpenApiDocumentor.cs
abhishekkumams Nov 8, 2023
db25bd8
fixing nits
Nov 8, 2023
ef97b71
fixing nits
Nov 8, 2023
c6d0a6d
Merge branch 'main' into dev/abhishekkuma/open-api-documentor
abhishekkumams Nov 13, 2023
4e05b01
fixing nits
Nov 13, 2023
66d6e5c
fixing tests
Nov 13, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions src/Core/Parsers/RequestParser.cs
Original file line number Diff line number Diff line change
Expand Up @@ -18,23 +18,23 @@ public class RequestParser
/// <summary>
/// Prefix used for specifying the fields in the query string of the URL.
/// </summary>
private const string FIELDS_URL = "$select";
public const string FIELDS_URL = "$select";
/// <summary>
/// Prefix used for specifying the fields to be used to sort the result in the query string of the URL.
/// </summary>
private const string SORT_URL = "$orderby";
public const string SORT_URL = "$orderby";
/// <summary>
/// Prefix used for specifying filter in the query string of the URL.
/// </summary>
public const string FILTER_URL = "$filter";
/// <summary>
/// Prefix used for specifying limit in the query string of the URL.
/// </summary>
private const string FIRST_URL = "$first";
public const string FIRST_URL = "$first";
/// <summary>
/// Prefix used for specifying paging in the query string of the URL.
/// </summary>
private const string AFTER_URL = "$after";
public const string AFTER_URL = "$after";

/// <summary>
/// Parses the primary key string to identify the field names composing the key
Expand Down
116 changes: 116 additions & 0 deletions src/Core/Services/OpenAPI/OpenApiDocumentor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
using Azure.DataApiBuilder.Config.DatabasePrimitives;
using Azure.DataApiBuilder.Config.ObjectModel;
using Azure.DataApiBuilder.Core.Configurations;
using Azure.DataApiBuilder.Core.Parsers;
using Azure.DataApiBuilder.Core.Services.MetadataProviders;
using Azure.DataApiBuilder.Service.Exceptions;
using Microsoft.OpenApi.Models;
Expand Down Expand Up @@ -45,6 +46,8 @@ public class OpenApiDocumentor : IOpenApiDocumentor
// Routing constant
public const string OPENAPI_ROUTE = "openapi";

// OpenApi query parameters
private static readonly List<OpenApiParameter> _tableAndViewQueryParameters = CreateTableAndViewQueryParameters();
// Error messages
public const string DOCUMENT_ALREADY_GENERATED_ERROR = "OpenAPI description document already generated.";
public const string DOCUMENT_CREATION_UNSUPPORTED_ERROR = "OpenAPI description document can't be created when the REST endpoint is disabled globally.";
Expand Down Expand Up @@ -284,7 +287,9 @@ private Dictionary<OperationType, OpenApiOperation> CreateOperations(
// The OpenApiResponses dictionary key represents the integer value of the HttpStatusCode,
// which is returned when using Enum.ToString("D").
// The "D" format specified "displays the enumeration entry as an integer value in the shortest representation possible."
// It will only contain $select query parameter to allow the user to specify which fields to return.
OpenApiOperation getOperation = CreateBaseOperation(description: GETONE_DESCRIPTION, tags: tags);
getOperation.Parameters = _tableAndViewQueryParameters;
getOperation.Responses.Add(HttpStatusCode.OK.ToString("D"), CreateOpenApiResponse(description: nameof(HttpStatusCode.OK), responseObjectSchemaName: entityName));
openApiPathItemOperations.Add(OperationType.Get, getOperation);

Expand Down Expand Up @@ -317,6 +322,7 @@ private Dictionary<OperationType, OpenApiOperation> CreateOperations(
{
// Primary key(s) are not included in the URI paths of the GET (all) and POST operations.
OpenApiOperation getAllOperation = CreateBaseOperation(description: GETALL_DESCRIPTION, tags: tags);
getAllOperation.Parameters = _tableAndViewQueryParameters;
getAllOperation.Responses.Add(
HttpStatusCode.OK.ToString("D"),
CreateOpenApiResponse(description: nameof(HttpStatusCode.OK), responseObjectSchemaName: entityName, includeNextLink: true));
Expand Down Expand Up @@ -360,6 +366,7 @@ private Dictionary<OperationType, OpenApiOperation> CreateStoredProcedureOperati
if (configuredRestOperations[OperationType.Get])
{
OpenApiOperation getOperation = CreateBaseOperation(description: SP_EXECUTE_DESCRIPTION, tags: tags);
getOperation.Parameters = CreateStoredProcedureInputParameters((StoredProcedureDefinition)sourceDefinition);
getOperation.Responses.Add(
HttpStatusCode.OK.ToString("D"),
CreateOpenApiResponse(
Expand Down Expand Up @@ -431,6 +438,115 @@ private OpenApiOperation CreateBaseOperation(string description, List<OpenApiTag
return operation;
}

/// <summary>
/// This method creates a list of OpenApiParameter objects for the input parameters of a stored procedure.
/// A input parameter will be marked REQUIRED if default value is not available.
/// </summary>
private static List<OpenApiParameter> CreateStoredProcedureInputParameters(StoredProcedureDefinition spDefinition)
{
List<OpenApiParameter> parameters = new();

foreach ((string paramKey, ParameterDefinition parameterDefinition) in spDefinition.Parameters)
{
parameters.Add(
GetOpenApiQueryParameter(
name: paramKey,
description: "Input parameter for stored procedure arguments",
required: false,
type: TypeHelper.GetJsonDataTypeFromSystemType(parameterDefinition.SystemType).ToString().ToLower()
)
);
}

return parameters;
}

/// <summary>
/// Creates a list of OpenAPI parameters for querying tables and views.
/// The query parameters include $select, $filter, $orderby, $first, and $after, which allow the user to specify which fields to return,
/// filter the results based on a predicate expression, sort the results, and paginate the results.
/// </summary>
/// <returns>A list of OpenAPI parameters.</returns>
private static List<OpenApiParameter> CreateTableAndViewQueryParameters()
{
List<OpenApiParameter> parameters = new();
Comment thread
abhishekkumams marked this conversation as resolved.
Resolved

// Add $select query parameter
parameters.Add(
GetOpenApiQueryParameter(
name: RequestParser.FIELDS_URL,
Comment thread
abhishekkumams marked this conversation as resolved.
Resolved
description: "A comma separated list of fields to return in the response.",
Comment thread
abhishekkumams marked this conversation as resolved.
Resolved
required: false,
type: "string"
)
);

// Add $filter query parameter
parameters.Add(
GetOpenApiQueryParameter(
name: RequestParser.FILTER_URL,
description: "An OData expression (an expression that returns a boolean value) using the entity's fields to retrieve a subset of the results.",
required: false,
type: "string"
)
);

// Add $orderby query parameter
parameters.Add(
GetOpenApiQueryParameter(
name: RequestParser.SORT_URL,
description: "Uses a comma-separated list of expressions to sort response items. Add 'desc' for descending order, otherwise it's ascending by default.",
required: false,
type: "string"
)
);

// Add $first query parameter
parameters.Add(
GetOpenApiQueryParameter(
name: RequestParser.FIRST_URL,
description: "An integer value that specifies the number of items to return. Default is 100.",
required: false,
type: "integer"
)
);

// Add $after query parameter
parameters.Add(
GetOpenApiQueryParameter(
name: RequestParser.AFTER_URL,
description: "An opaque string that specifies the cursor position after which results should be returned.",
required: false,
type: "string"
)
);

return parameters;
}

/// <summary>
/// Creates a new OpenAPI query parameter with the specified name, description, required flag, and data type.
/// </summary>
/// <param name="name">The name of the query parameter.</param>
/// <param name="description">The description of the query parameter.</param>
/// <param name="required">A flag indicating whether the query parameter is required.</param>
/// <param name="type">The data type of the query parameter.</param>
/// <returns>A new OpenAPI query parameter.</returns>
private static OpenApiParameter GetOpenApiQueryParameter(string name, string description, bool required, string type)
{
return new OpenApiParameter
{
Name = name,
In = ParameterLocation.Query,
Description = description,
Required = required,
Schema = new OpenApiSchema
{
Type = type
}
};
}

/// <summary>
/// Returns collection of OpenAPI OperationTypes and associated flag indicating whether they are enabled
/// for the engine's REST endpoint.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ internal class OpenApiTestBootstrap
/// <param name="configFileName"></param>
/// <param name="databaseEnvironment"></param>
/// <returns>Generated OpenApiDocument</returns>
internal static async Task<OpenApiDocument> GenerateOpenApiDocument(
internal static async Task<OpenApiDocument> GenerateOpenApiDocumentAsync(
RuntimeEntities runtimeEntities,
string configFileName,
string databaseEnvironment)
Expand Down
Loading