Skip to content

Order Search Swagger documentation with duplicate values #660

Description

@nunoaguiar

Is your feature request related to a problem? Please describe.

GET /dwapi/ecommerce/orders/search (Orders_SearchOrders) emits 81 query parameters, 5 of which are declared twice in the same operation:

Parameter Occurrences
PageSize 2
FromCompletedDate 2
ToCompletedDate 2
ByCustomerNumber 2
RetrieveMode 2

The cause is in the action signature (Dynamicweb.Frontend.Classic.Api.Ecommerce/Controllers/OrdersController.cs):

[HttpGet, Route("search")]
public IActionResult SearchOrders([FromQuery] OrderSearchRequest request,
                                  [FromQuery] OrderListViewModelSettings settings)

Two complex models are bound from the query string with no binder prefix on either. OrderSearchRequest declares PageSize, FromCompletedDate, ToCompletedDate, ByCustomerNumber, RetrieveMode; OrderListViewModelSettings declares the same five. NSwag flattens both models into the same parameter list, so each name is emitted once per model. Nested settings are namespaced (OrderSettings.PriceSettings.ShopId, …) and therefore don't collide — only the top-level properties of the second model do.

Why this is a problem:

  1. The document is invalid OpenAPI. OpenAPI 3.0 requires parameters to be unique by name + in. Downstream tooling reacts unpredictably: NSwag/openapi-generator produce a client method with two identically named arguments (compile error) or silently drop one, and linters (Spectral, Redocly) fail the document.

  2. Swagger UI renders two identical input boxes for each duplicated field, with no way for a consumer to tell which one is which or which one wins.

  3. The duplicates are inert, which makes it worse. ASP.NET binds the same value into both objects, and then the controller immediately overwrites the settings copy:

    settings.PageSize = request.PageSize;
    settings.CurrentPage = request.Page;

    settings.FromCompletedDate, settings.ToCompletedDate, settings.RetrieveMode and settings.ByCustomerNumber are bound but never read — only request.* feeds the search filter. So half the documented surface of this endpoint has no effect at all.

  4. Passing the parameter twice (?PageSize=10&PageSize=25) does not error — the first value silently wins — so the ambiguity fails quietly rather than loudly.

Page vs CurrentPage
Also worth noting as context for the same root cause: paging is near-duplicated under two spellings (Page on the request vs CurrentPage on the settings), and both are documented.

Describe the solution you'd like

Every operation in the generated document should have parameters that are unique by name + location. Concretely, for this endpoint:

  1. Prefix or eliminate the second bound model. Either bind the view settings under a name — [FromQuery(Name = "settings")] OrderListViewModelSettings settings, yielding settings.PageSize, settings.ShowPricesWithVat, … — or, preferably, stop binding OrderListViewModelSettings from the query string entirely and expose a slim API-specific settings model that omits the properties already carried by OrderSearchRequest. The latter also removes the four parameters the endpoint documents but ignores.
  2. Drop or collapse the redundant paging spelling so there is one Page/PageSize pair on the endpoint, not two.
  3. Guard it in CI. There is currently no test that generates the OpenAPI document and asserts anything about it. A single test that builds the NSwag document and asserts parameters are distinct by (name, in) for every operation would prevent this class of regression across the whole API, not just this endpoint.
  4. Please treat the querystring contract change as a versioning decision — if the current unprefixed names must keep working, accepting both the prefixed and legacy names for a deprecation window would avoid breaking existing consumers.

Additional context

  • Verified against https://staging-jayco.mydwsite.com/dwapi/api.json, info.version = 10.29.1-PreRelease.
  • Scanned all 125 operations in that document: Orders_SearchOrders is currently the only one with duplicate parameter names, so the fix is narrow.
  • Related but separate concern from the same "bind several complex models from the query string" pattern: parameter explosion. Orders_SearchOrders has 81 query parameters and Products_ExportProducts has 156, most of them deeply dotted (OrderSettings.OrderLineSettings.GroupInfoSettings.CurrencyCode). These operations are effectively unusable through Swagger UI even when the parameters are unique. A POST-with-body variant for the wide search/export operations would help here.
  • Relevant files: Dynamicweb.Frontend.Classic.Api.Ecommerce/Controllers/OrdersController.cs, Dynamicweb.Frontend.Classic.Api.Ecommerce/Controllers/OrderSearchRequest.cs, src/Features/Ecommerce/Dynamicweb.Ecommerce/Frontend/OrderListViewModelSettings.cs, and the document generation setup in Dynamicweb.Frontend.Classic.Api/ServiceCollectionExtensions.cs (AddOpenApiDocument).

Best Regards,
Nuno Aguiar

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions