diff --git a/sdk/dotnet/src/Microsoft.AspNetCore.Datasync.Swashbuckle/DatasyncDocumentFilter.cs b/sdk/dotnet/src/Microsoft.AspNetCore.Datasync.Swashbuckle/DatasyncDocumentFilter.cs index 0e64ef71f..5dfadbc82 100644 --- a/sdk/dotnet/src/Microsoft.AspNetCore.Datasync.Swashbuckle/DatasyncDocumentFilter.cs +++ b/sdk/dotnet/src/Microsoft.AspNetCore.Datasync.Swashbuckle/DatasyncDocumentFilter.cs @@ -2,6 +2,7 @@ // Licensed under the MIT License. using Microsoft.AspNetCore.Mvc; +using Microsoft.AspNetCore.Mvc.ApiExplorer; using Microsoft.OpenApi.Models; using Swashbuckle.AspNetCore.SwaggerGen; using System; @@ -39,7 +40,7 @@ private enum OpType /// /// The assembly to query for TableController instances, if any. If none is provided, the calling assembly is queried. /// - private Assembly assemblyToQuery = null; + private readonly Assembly assemblyToQuery = null; /// /// Creates a new . @@ -68,11 +69,11 @@ public void Apply(OpenApiDocument document, DocumentFilterContext context) if (entityType == null) continue; - var routeAttribute = controller.GetCustomAttribute(); - if (routeAttribute == null) + var routePath = context.ApiDescriptions.FirstOrDefault(m => IsApiDescriptionForController(m, controller))?.RelativePath; + if (routePath == null) continue; - var allEntitiesPath = $"/{routeAttribute.Template}"; - var singleEntityPath = $"/{routeAttribute.Template}/{{id}}"; + var allEntitiesPath = $"/{routePath}"; + var singleEntityPath = $"/{routePath}/{{id}}"; // Get the various operations Dictionary operations = new() @@ -176,6 +177,21 @@ public void Apply(OpenApiDocument document, DocumentFilterContext context) } } } + + /// + /// Determines if the controller type is represented by the API Description. + /// + /// The being handled. + /// The type of the controller being used. + /// true if the Api description represents the controller. + internal static bool IsApiDescriptionForController(ApiDescription description, Type controllerType) + { + if (description.TryGetMethodInfo(out MethodInfo methodInfo)) + { + return methodInfo.ReflectedType == controllerType && (methodInfo.Name.Equals("GetAsync") || methodInfo.Name.Equals("CreateAsync")); + } + return false; + } /// /// Returns a list of all table controllers in the provided assembly. diff --git a/sdk/dotnet/test/Microsoft.AspNetCore.Datasync.NSwag.Test/Service/KitchenSink.cs b/sdk/dotnet/test/Microsoft.AspNetCore.Datasync.NSwag.Test/Service/Models.cs similarity index 85% rename from sdk/dotnet/test/Microsoft.AspNetCore.Datasync.NSwag.Test/Service/KitchenSink.cs rename to sdk/dotnet/test/Microsoft.AspNetCore.Datasync.NSwag.Test/Service/Models.cs index 5c794436a..4a3b9d078 100644 --- a/sdk/dotnet/test/Microsoft.AspNetCore.Datasync.NSwag.Test/Service/KitchenSink.cs +++ b/sdk/dotnet/test/Microsoft.AspNetCore.Datasync.NSwag.Test/Service/Models.cs @@ -5,10 +5,12 @@ namespace Microsoft.AspNetCore.Datasync.NSwag.Test.Service { - /// - /// A model used for validation tests. It contains one of - /// every single supported type in a nullable form. - /// + [ExcludeFromCodeCoverage] + public class TodoItem : EntityTableData + { + public string? Title { get; set; } + } + [ExcludeFromCodeCoverage] public class KitchenSink : EntityTableData { diff --git a/sdk/dotnet/test/Microsoft.AspNetCore.Datasync.NSwag.Test/Service/ServiceDbContext.cs b/sdk/dotnet/test/Microsoft.AspNetCore.Datasync.NSwag.Test/Service/ServiceDbContext.cs index de69814cb..6b7fb85c7 100644 --- a/sdk/dotnet/test/Microsoft.AspNetCore.Datasync.NSwag.Test/Service/ServiceDbContext.cs +++ b/sdk/dotnet/test/Microsoft.AspNetCore.Datasync.NSwag.Test/Service/ServiceDbContext.cs @@ -22,6 +22,11 @@ public ServiceDbContext(DbContextOptions options) : base(optio /// public DbSet KitchenSinks => Set(); + /// + /// The set of TodoItem values + /// + public DbSet TodoItems => Set(); + /// /// Initializes the current database /// diff --git a/sdk/dotnet/test/Microsoft.AspNetCore.Datasync.NSwag.Test/Service/TodoItemController.cs b/sdk/dotnet/test/Microsoft.AspNetCore.Datasync.NSwag.Test/Service/TodoItemController.cs new file mode 100644 index 000000000..ba4d30e84 --- /dev/null +++ b/sdk/dotnet/test/Microsoft.AspNetCore.Datasync.NSwag.Test/Service/TodoItemController.cs @@ -0,0 +1,21 @@ +// Copyright (c) Microsoft Corporation. All Rights Reserved. +// Licensed under the MIT License. + +using Microsoft.AspNetCore.Datasync.EFCore; +using Microsoft.AspNetCore.Mvc; +using Microsoft.Extensions.Logging; +using System.Diagnostics.CodeAnalysis; + +namespace Microsoft.AspNetCore.Datasync.NSwag.Test.Service +{ + [Route("tables/[controller]")] + [ExcludeFromCodeCoverage] + public class TodoItemController : TableController + { + public TodoItemController(ServiceDbContext context, ILogger logger) : base() + { + Repository = new EntityTableRepository(context); + Logger = logger; + } + } +} diff --git a/sdk/dotnet/test/Microsoft.AspNetCore.Datasync.NSwag.Test/swagger.json b/sdk/dotnet/test/Microsoft.AspNetCore.Datasync.NSwag.Test/swagger.json index 489352a4b..673c20925 100644 --- a/sdk/dotnet/test/Microsoft.AspNetCore.Datasync.NSwag.Test/swagger.json +++ b/sdk/dotnet/test/Microsoft.AspNetCore.Datasync.NSwag.Test/swagger.json @@ -635,6 +635,631 @@ } } } + }, + "/tables/TodoItem": { + "post": { + "tags": [ + "TodoItem" + ], + "operationId": "TodoItem_Create", + "parameters": [ + { + "name": "ZUMO-API-VERSION", + "in": "header", + "required": true, + "description": "Sets the Datasync API version to use.", + "schema": { + "type": "string", + "enum": [ + "3.0.0", + "2.0.0" + ] + } + }, + { + "name": "If-None-Match", + "in": "header", + "description": "Conditionally execute only if the entity version does not match the provided string (RFC 9110 13.1.2).", + "schema": { + "type": "string" + } + } + ], + "requestBody": { + "x-name": "item", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/TodoItem" + } + } + }, + "required": true, + "x-position": 1 + }, + "responses": { + "201": { + "description": "Created", + "headers": { + "ETag": { + "description": "The version string of the server entity, per RFC 9110", + "schema": { + "type": "string" + } + } + }, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/TodoItem" + } + } + } + }, + "409": { + "description": "Conflict", + "headers": { + "ETag": { + "description": "The version string of the server entity, per RFC 9110", + "schema": { + "type": "string" + } + } + }, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/TodoItem" + } + } + } + }, + "412": { + "description": "Precondition Failed", + "headers": { + "ETag": { + "description": "The version string of the server entity, per RFC 9110", + "schema": { + "type": "string" + } + } + }, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/TodoItem" + } + } + } + }, + "400": { + "description": "Bad Request" + } + } + }, + "get": { + "tags": [ + "TodoItem" + ], + "operationId": "TodoItem_Query", + "parameters": [ + { + "name": "ZUMO-API-VERSION", + "in": "header", + "required": true, + "description": "Sets the Datasync API version to use.", + "schema": { + "type": "string", + "enum": [ + "3.0.0", + "2.0.0" + ] + } + }, + { + "name": "$count", + "in": "query", + "description": "If true, return the total number of items matched by the filter", + "schema": { + "type": "boolean" + } + }, + { + "name": "$filter", + "in": "query", + "description": "An OData filter describing the entities to be returned", + "schema": { + "type": "string" + } + }, + { + "name": "$orderby", + "in": "query", + "description": "A comma-separated list of ordering instructions. Each ordering instruction is a field name with an optional direction (asc or desc).", + "schema": { + "type": "string" + } + }, + { + "name": "$select", + "in": "query", + "description": "A comma-separated list of fields to be returned in the result set.", + "schema": { + "type": "string" + } + }, + { + "name": "$skip", + "in": "query", + "description": "The number of items in the list to skip for paging support.", + "schema": { + "type": "integer" + } + }, + { + "name": "$top", + "in": "query", + "description": "The number of items in the list to return for paging support.", + "schema": { + "type": "integer" + } + }, + { + "name": "__includedeleted", + "in": "query", + "description": "If true, soft-deleted items are returned as well as non-deleted items.", + "schema": { + "type": "boolean" + } + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "type": "object", + "description": "A page of TodoItem entities", + "properties": { + "items": { + "type": "array", + "readOnly": true, + "description": "The entities in this page of results", + "nullable": true, + "items": { + "$ref": "#/components/schemas/TodoItem" + } + }, + "count": { + "type": "integer", + "readOnly": true, + "description": "The count of all entities in the result set", + "nullable": true + }, + "nextLink": { + "type": "string", + "readOnly": true, + "description": "The URI to the next page of entities", + "format": "uri", + "nullable": true + } + } + } + } + } + }, + "400": { + "description": "Bad Request" + } + } + } + }, + "/tables/TodoItem/{id}": { + "delete": { + "tags": [ + "TodoItem" + ], + "operationId": "TodoItem_Delete", + "parameters": [ + { + "name": "id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "nullable": true + }, + "x-position": 1 + }, + { + "name": "ZUMO-API-VERSION", + "in": "header", + "required": true, + "description": "Sets the Datasync API version to use.", + "schema": { + "type": "string", + "enum": [ + "3.0.0", + "2.0.0" + ] + } + }, + { + "name": "If-Match", + "in": "header", + "description": "Conditionally execute only if the entity version matches the provided string (RFC 9110 13.1.1).", + "schema": { + "type": "string" + } + } + ], + "responses": { + "204": { + "description": "No Content" + }, + "409": { + "description": "Conflict", + "headers": { + "ETag": { + "description": "The version string of the server entity, per RFC 9110", + "schema": { + "type": "string" + } + } + }, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/TodoItem" + } + } + } + }, + "412": { + "description": "Precondition Failed", + "headers": { + "ETag": { + "description": "The version string of the server entity, per RFC 9110", + "schema": { + "type": "string" + } + } + }, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/TodoItem" + } + } + } + }, + "404": { + "description": "Not Found" + }, + "410": { + "description": "Gone" + } + } + }, + "patch": { + "tags": [ + "TodoItem" + ], + "operationId": "TodoItem_Patch", + "parameters": [ + { + "name": "id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "nullable": true + }, + "x-position": 1 + }, + { + "name": "ZUMO-API-VERSION", + "in": "header", + "required": true, + "description": "Sets the Datasync API version to use.", + "schema": { + "type": "string", + "enum": [ + "3.0.0", + "2.0.0" + ] + } + }, + { + "name": "If-Match", + "in": "header", + "description": "Conditionally execute only if the entity version matches the provided string (RFC 9110 13.1.1).", + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "OK", + "headers": { + "ETag": { + "description": "The version string of the server entity, per RFC 9110", + "schema": { + "type": "string" + } + } + }, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/TodoItem" + } + } + } + }, + "409": { + "description": "Conflict", + "headers": { + "ETag": { + "description": "The version string of the server entity, per RFC 9110", + "schema": { + "type": "string" + } + } + }, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/TodoItem" + } + } + } + }, + "412": { + "description": "Precondition Failed", + "headers": { + "ETag": { + "description": "The version string of the server entity, per RFC 9110", + "schema": { + "type": "string" + } + } + }, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/TodoItem" + } + } + } + }, + "400": { + "description": "Bad Request" + }, + "404": { + "description": "Not Found" + }, + "410": { + "description": "Gone" + } + } + }, + "get": { + "tags": [ + "TodoItem" + ], + "operationId": "TodoItem_Read", + "parameters": [ + { + "name": "id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "nullable": true + }, + "x-position": 1 + }, + { + "name": "ZUMO-API-VERSION", + "in": "header", + "required": true, + "description": "Sets the Datasync API version to use.", + "schema": { + "type": "string", + "enum": [ + "3.0.0", + "2.0.0" + ] + } + }, + { + "name": "If-None-Match", + "in": "header", + "description": "Conditionally execute only if the entity version does not match the provided string (RFC 9110 13.1.2).", + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "OK", + "headers": { + "ETag": { + "description": "The version string of the server entity, per RFC 9110", + "schema": { + "type": "string" + } + } + }, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/TodoItem" + } + } + } + }, + "409": { + "description": "Conflict", + "headers": { + "ETag": { + "description": "The version string of the server entity, per RFC 9110", + "schema": { + "type": "string" + } + } + }, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/TodoItem" + } + } + } + }, + "412": { + "description": "Precondition Failed", + "headers": { + "ETag": { + "description": "The version string of the server entity, per RFC 9110", + "schema": { + "type": "string" + } + } + }, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/TodoItem" + } + } + } + }, + "404": { + "description": "Not Found" + } + } + }, + "put": { + "tags": [ + "TodoItem" + ], + "operationId": "TodoItem_Replace", + "parameters": [ + { + "name": "id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "nullable": true + }, + "x-position": 1 + }, + { + "name": "ZUMO-API-VERSION", + "in": "header", + "required": true, + "description": "Sets the Datasync API version to use.", + "schema": { + "type": "string", + "enum": [ + "3.0.0", + "2.0.0" + ] + } + }, + { + "name": "If-Match", + "in": "header", + "description": "Conditionally execute only if the entity version matches the provided string (RFC 9110 13.1.1).", + "schema": { + "type": "string" + } + } + ], + "requestBody": { + "x-name": "item", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/TodoItem" + } + } + }, + "required": true, + "x-position": 2 + }, + "responses": { + "200": { + "description": "OK", + "headers": { + "ETag": { + "description": "The version string of the server entity, per RFC 9110", + "schema": { + "type": "string" + } + } + }, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/TodoItem" + } + } + } + }, + "409": { + "description": "Conflict", + "headers": { + "ETag": { + "description": "The version string of the server entity, per RFC 9110", + "schema": { + "type": "string" + } + } + }, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/TodoItem" + } + } + } + }, + "412": { + "description": "Precondition Failed", + "headers": { + "ETag": { + "description": "The version string of the server entity, per RFC 9110", + "schema": { + "type": "string" + } + } + }, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/TodoItem" + } + } + } + }, + "400": { + "description": "Bad Request" + }, + "404": { + "description": "Not Found" + }, + "410": { + "description": "Gone" + } + } + } } }, "components": { @@ -722,6 +1347,23 @@ "readOnly": true } } + }, + "TodoItem": { + "allOf": [ + { + "$ref": "#/components/schemas/EntityTableData" + }, + { + "type": "object", + "additionalProperties": false, + "properties": { + "title": { + "type": "string", + "nullable": true + } + } + } + ] } } } diff --git a/sdk/dotnet/test/Microsoft.AspNetCore.Datasync.Swashbuckle.Test/Microsoft.AspNetCore.Datasync.Swashbuckle.Test.csproj b/sdk/dotnet/test/Microsoft.AspNetCore.Datasync.Swashbuckle.Test/Microsoft.AspNetCore.Datasync.Swashbuckle.Test.csproj index 3444686c7..7d57f53ac 100644 --- a/sdk/dotnet/test/Microsoft.AspNetCore.Datasync.Swashbuckle.Test/Microsoft.AspNetCore.Datasync.Swashbuckle.Test.csproj +++ b/sdk/dotnet/test/Microsoft.AspNetCore.Datasync.Swashbuckle.Test/Microsoft.AspNetCore.Datasync.Swashbuckle.Test.csproj @@ -39,4 +39,6 @@ + + diff --git a/sdk/dotnet/test/Microsoft.AspNetCore.Datasync.Swashbuckle.Test/Service/KitchenSink.cs b/sdk/dotnet/test/Microsoft.AspNetCore.Datasync.Swashbuckle.Test/Service/Models.cs similarity index 85% rename from sdk/dotnet/test/Microsoft.AspNetCore.Datasync.Swashbuckle.Test/Service/KitchenSink.cs rename to sdk/dotnet/test/Microsoft.AspNetCore.Datasync.Swashbuckle.Test/Service/Models.cs index 338579741..863443c6d 100644 --- a/sdk/dotnet/test/Microsoft.AspNetCore.Datasync.Swashbuckle.Test/Service/KitchenSink.cs +++ b/sdk/dotnet/test/Microsoft.AspNetCore.Datasync.Swashbuckle.Test/Service/Models.cs @@ -5,10 +5,12 @@ namespace Microsoft.AspNetCore.Datasync.Swashbuckle.Test.Service { - /// - /// A model used for validation tests. It contains one of - /// every single supported type in a nullable form. - /// + [ExcludeFromCodeCoverage] + public class TodoItem : EntityTableData + { + public string? Title { get; set; } + } + [ExcludeFromCodeCoverage] public class KitchenSink : EntityTableData { diff --git a/sdk/dotnet/test/Microsoft.AspNetCore.Datasync.Swashbuckle.Test/Service/ServiceDbContext.cs b/sdk/dotnet/test/Microsoft.AspNetCore.Datasync.Swashbuckle.Test/Service/ServiceDbContext.cs index d99158660..c59c18988 100644 --- a/sdk/dotnet/test/Microsoft.AspNetCore.Datasync.Swashbuckle.Test/Service/ServiceDbContext.cs +++ b/sdk/dotnet/test/Microsoft.AspNetCore.Datasync.Swashbuckle.Test/Service/ServiceDbContext.cs @@ -21,6 +21,11 @@ public ServiceDbContext(DbContextOptions options) : base(optio /// The set of kitchen sink values /// public DbSet KitchenSinks => Set(); + + /// + /// The set of TodoItem values + /// + public DbSet TodoItems => Set(); /// /// Initializes the current database diff --git a/sdk/dotnet/test/Microsoft.AspNetCore.Datasync.Swashbuckle.Test/Service/TodoItemController.cs b/sdk/dotnet/test/Microsoft.AspNetCore.Datasync.Swashbuckle.Test/Service/TodoItemController.cs new file mode 100644 index 000000000..a5b049e59 --- /dev/null +++ b/sdk/dotnet/test/Microsoft.AspNetCore.Datasync.Swashbuckle.Test/Service/TodoItemController.cs @@ -0,0 +1,21 @@ +// Copyright (c) Microsoft Corporation. All Rights Reserved. +// Licensed under the MIT License. + +using Microsoft.AspNetCore.Datasync.EFCore; +using Microsoft.AspNetCore.Mvc; +using Microsoft.Extensions.Logging; +using System.Diagnostics.CodeAnalysis; + +namespace Microsoft.AspNetCore.Datasync.Swashbuckle.Test.Service +{ + [Route("tables/[controller]")] + [ExcludeFromCodeCoverage] + public class TodoItemController : TableController + { + public TodoItemController(ServiceDbContext context, ILogger logger) : base() + { + Repository = new EntityTableRepository(context); + Logger = logger; + } + } +} diff --git a/sdk/dotnet/test/Microsoft.AspNetCore.Datasync.Swashbuckle.Test/SwaggerGen_Tests.cs b/sdk/dotnet/test/Microsoft.AspNetCore.Datasync.Swashbuckle.Test/SwaggerGen_Tests.cs index d0c18b846..6e226eec1 100644 --- a/sdk/dotnet/test/Microsoft.AspNetCore.Datasync.Swashbuckle.Test/SwaggerGen_Tests.cs +++ b/sdk/dotnet/test/Microsoft.AspNetCore.Datasync.Swashbuckle.Test/SwaggerGen_Tests.cs @@ -10,13 +10,13 @@ namespace Microsoft.AspNetCore.Datasync.Swashbuckle.Test { public class SwaggerGen_Tests { - private TestServer server = SwaggerServer.CreateTestServer(); + private readonly TestServer server = SwaggerServer.CreateTestServer(); private static string ReadExternalFile(string filename) { Assembly asm = Assembly.GetExecutingAssembly(); using Stream s = asm.GetManifestResourceStream(asm.GetName().Name + "." + filename)!; - using StreamReader sr = new StreamReader(s); + using StreamReader sr = new(s); return sr.ReadToEnd(); } @@ -25,9 +25,12 @@ public void DocumentFilter_ReadsAllControllers() { Assert.NotNull(server); - var controllers = DatasyncDocumentFilter.GetAllTableControllers(); - Assert.Single(controllers); - Assert.Equal("KitchenSinkController", controllers.First().Name); + var controllers = DatasyncDocumentFilter.GetAllTableControllers().Select(m => m.Name).ToList(); + + // There should be two controllers + Assert.Equal(2, controllers.Count); + Assert.Contains("KitchenSinkController", controllers); + Assert.Contains("TodoItemController", controllers); } [Fact] diff --git a/sdk/dotnet/test/Microsoft.AspNetCore.Datasync.Swashbuckle.Test/swagger.json b/sdk/dotnet/test/Microsoft.AspNetCore.Datasync.Swashbuckle.Test/swagger.json index e7b030555..ec1f1b2df 100644 --- a/sdk/dotnet/test/Microsoft.AspNetCore.Datasync.Swashbuckle.Test/swagger.json +++ b/sdk/dotnet/test/Microsoft.AspNetCore.Datasync.Swashbuckle.Test/swagger.json @@ -559,6 +559,561 @@ } } } + }, + "/tables/TodoItem": { + "post": { + "tags": [ + "TodoItem" + ], + "parameters": [ + { + "name": "ZUMO-API-VERSION", + "in": "header", + "description": "Datasync protocol version to be used.", + "required": true, + "schema": { + "enum": [ + "3.0.0", + "2.0.0" + ], + "type": "string" + } + }, + { + "name": "If-None-Match", + "in": "header", + "description": "Conditionally execute only if the entity version does not match the provided string (RFC 9110 13.1.2).", + "schema": { + "type": "string" + } + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/TodoItem" + } + } + } + }, + "responses": { + "201": { + "description": "Created", + "headers": { + "ETag": { + "description": "The opaque versioning identifier of the entity, per RFC 9110 8.8.3.", + "schema": { + "type": "string" + } + } + }, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/TodoItem" + } + } + } + }, + "400": { + "description": "Bad Request" + }, + "409": { + "description": "Conflict", + "headers": { + "ETag": { + "description": "The opaque versioning identifier of the conflicting entity, per RFC 9110 8.8.3.", + "schema": { + "type": "string" + } + } + }, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/TodoItem" + } + } + } + }, + "412": { + "description": "Precondition failed", + "headers": { + "ETag": { + "description": "The opaque versioning identifier of the conflicting entity, per RFC 9110 8.8.3.", + "schema": { + "type": "string" + } + } + }, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/TodoItem" + } + } + } + } + } + }, + "get": { + "tags": [ + "TodoItem" + ], + "parameters": [ + { + "name": "ZUMO-API-VERSION", + "in": "header", + "description": "Datasync protocol version to be used.", + "required": true, + "schema": { + "enum": [ + "3.0.0", + "2.0.0" + ], + "type": "string" + } + }, + { + "name": "$count", + "in": "query", + "description": "If true, return the total number of items matched by the filter", + "schema": { + "type": "boolean" + } + }, + { + "name": "$filter", + "in": "query", + "description": "An OData filter describing the entities to be returned", + "schema": { + "type": "string" + } + }, + { + "name": "$orderby", + "in": "query", + "description": "A comma-separated list of ordering instructions. Each ordering instruction is a field name with an optional direction (asc or desc).", + "schema": { + "type": "string" + } + }, + { + "name": "$select", + "in": "query", + "description": "A comma-separated list of fields to be returned in the result set.", + "schema": { + "type": "string" + } + }, + { + "name": "$skip", + "in": "query", + "description": "The number of items in the list to skip for paging support.", + "schema": { + "type": "integer" + } + }, + { + "name": "$top", + "in": "query", + "description": "The number of items in the list to return for paging support.", + "schema": { + "type": "integer" + } + }, + { + "name": "__includedeleted", + "in": "query", + "description": "If true, soft-deleted items are returned as well as non-deleted items.", + "schema": { + "type": "boolean" + } + } + ], + "responses": { + "200": { + "description": "OK", + "headers": { + "ETag": { + "description": "The opaque versioning identifier of the entity, per RFC 9110 8.8.3.", + "schema": { + "type": "string" + } + } + }, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/TodoItemPage" + } + } + } + }, + "400": { + "description": "Bad Request" + } + } + } + }, + "/tables/TodoItem/{id}": { + "delete": { + "tags": [ + "TodoItem" + ], + "parameters": [ + { + "name": "id", + "in": "path", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "ZUMO-API-VERSION", + "in": "header", + "description": "Datasync protocol version to be used.", + "required": true, + "schema": { + "enum": [ + "3.0.0", + "2.0.0" + ], + "type": "string" + } + }, + { + "name": "If-Match", + "in": "header", + "description": "Conditionally execute only if the entity version matches the provided string (RFC 9110 13.1.1).", + "schema": { + "type": "string" + } + } + ], + "responses": { + "204": { + "description": "No Content" + }, + "404": { + "description": "Not Found" + }, + "410": { + "description": "Gone" + }, + "409": { + "description": "Conflict", + "headers": { + "ETag": { + "description": "The opaque versioning identifier of the conflicting entity, per RFC 9110 8.8.3.", + "schema": { + "type": "string" + } + } + }, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/TodoItem" + } + } + } + }, + "412": { + "description": "Precondition failed", + "headers": { + "ETag": { + "description": "The opaque versioning identifier of the conflicting entity, per RFC 9110 8.8.3.", + "schema": { + "type": "string" + } + } + }, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/TodoItem" + } + } + } + } + } + }, + "patch": { + "tags": [ + "TodoItem" + ], + "parameters": [ + { + "name": "id", + "in": "path", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "ZUMO-API-VERSION", + "in": "header", + "description": "Datasync protocol version to be used.", + "required": true, + "schema": { + "enum": [ + "3.0.0", + "2.0.0" + ], + "type": "string" + } + }, + { + "name": "If-Match", + "in": "header", + "description": "Conditionally execute only if the entity version matches the provided string (RFC 9110 13.1.1).", + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "OK", + "headers": { + "ETag": { + "description": "The opaque versioning identifier of the entity, per RFC 9110 8.8.3.", + "schema": { + "type": "string" + } + } + }, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/TodoItem" + } + } + } + }, + "400": { + "description": "Bad Request" + }, + "404": { + "description": "Not Found" + }, + "410": { + "description": "Gone" + }, + "409": { + "description": "Conflict", + "headers": { + "ETag": { + "description": "The opaque versioning identifier of the conflicting entity, per RFC 9110 8.8.3.", + "schema": { + "type": "string" + } + } + }, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/TodoItem" + } + } + } + }, + "412": { + "description": "Precondition failed", + "headers": { + "ETag": { + "description": "The opaque versioning identifier of the conflicting entity, per RFC 9110 8.8.3.", + "schema": { + "type": "string" + } + } + }, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/TodoItem" + } + } + } + } + } + }, + "get": { + "tags": [ + "TodoItem" + ], + "parameters": [ + { + "name": "id", + "in": "path", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "ZUMO-API-VERSION", + "in": "header", + "description": "Datasync protocol version to be used.", + "required": true, + "schema": { + "enum": [ + "3.0.0", + "2.0.0" + ], + "type": "string" + } + }, + { + "name": "If-None-Match", + "in": "header", + "description": "Conditionally execute only if the entity version does not match the provided string (RFC 9110 13.1.2).", + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "OK", + "headers": { + "ETag": { + "description": "The opaque versioning identifier of the entity, per RFC 9110 8.8.3.", + "schema": { + "type": "string" + } + } + }, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/TodoItem" + } + } + } + }, + "304": { + "description": "Not Modified" + }, + "404": { + "description": "Not Found" + } + } + }, + "put": { + "tags": [ + "TodoItem" + ], + "parameters": [ + { + "name": "id", + "in": "path", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "ZUMO-API-VERSION", + "in": "header", + "description": "Datasync protocol version to be used.", + "required": true, + "schema": { + "enum": [ + "3.0.0", + "2.0.0" + ], + "type": "string" + } + }, + { + "name": "If-Match", + "in": "header", + "description": "Conditionally execute only if the entity version matches the provided string (RFC 9110 13.1.1).", + "schema": { + "type": "string" + } + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/TodoItem" + } + } + } + }, + "responses": { + "200": { + "description": "OK", + "headers": { + "ETag": { + "description": "The opaque versioning identifier of the entity, per RFC 9110 8.8.3.", + "schema": { + "type": "string" + } + } + }, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/TodoItem" + } + } + } + }, + "400": { + "description": "Bad Request" + }, + "404": { + "description": "Not Found" + }, + "410": { + "description": "Gone" + }, + "409": { + "description": "Conflict", + "headers": { + "ETag": { + "description": "The opaque versioning identifier of the conflicting entity, per RFC 9110 8.8.3.", + "schema": { + "type": "string" + } + } + }, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/TodoItem" + } + } + } + }, + "412": { + "description": "Precondition failed", + "headers": { + "ETag": { + "description": "The opaque versioning identifier of the conflicting entity, per RFC 9110 8.8.3.", + "schema": { + "type": "string" + } + } + }, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/TodoItem" + } + } + } + } + } + } } }, "components": { @@ -658,6 +1213,61 @@ } }, "additionalProperties": false + }, + "TodoItem": { + "type": "object", + "properties": { + "title": { + "type": "string", + "nullable": true + }, + "id": { + "type": "string", + "nullable": true + }, + "updatedAt": { + "type": "string", + "format": "date-time", + "readOnly": true + }, + "version": { + "type": "string", + "format": "byte", + "nullable": true, + "readOnly": true + }, + "deleted": { + "type": "boolean", + "readOnly": true + } + }, + "additionalProperties": false + }, + "TodoItemPage": { + "type": "object", + "properties": { + "items": { + "type": "array", + "items": { + "$ref": "#/components/schemas/TodoItem" + }, + "nullable": true, + "readOnly": true + }, + "count": { + "type": "integer", + "format": "int64", + "nullable": true, + "readOnly": true + }, + "nextLink": { + "type": "string", + "format": "uri", + "nullable": true, + "readOnly": true + } + }, + "additionalProperties": false } } }