Skip to content

Support various JADNC controller types #1052

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
maurei opened this issue Sep 1, 2021 · 1 comment
Closed

Support various JADNC controller types #1052

maurei opened this issue Sep 1, 2021 · 1 comment
Labels

Comments

@maurei
Copy link
Member

maurei commented Sep 1, 2021

Currently the OpenApi integration only picks up on controllers that inherit from JsonApiController. This needs to be expanded so that the following are also picked up on:

  • JsonApiQueryController
  • JsonApiCommandController
  • Usages of HttpRestrictAttribute
  • Overrides of JsonApiController methods
  • Handling of [HttpHead]
@bkoelman
Copy link
Member

bkoelman commented Feb 11, 2024

Upon further investigation, I found this isn't as simple as it sounds.

The difficulty lies in the fact that JsonApiController<,> exposes action methods for all endpoints, only to throw from the unexposed ones. This was done to provide a more informative error response instead of just 404.

JsonApiQueryController and JsonApiCommandController inherit from JsonApiController, so they automatically expose all endpoints as well.

This means we can't rely on whether an action method exist to determine whether to expose an endpoint in OAS. We can't rely on the constructor parameters (IGetAllService, etc) either, because an action method may still be provided, containing logic that doesn't use the JsonApiDotNetCore pipeline.

As a compromise, I've ended up with the following:

  1. When [Resource(GenerateControllerEndpoints = ...)] is used with a value other than None, this means that auto-generated controllers are being used. All JSON:API endpoints not in the specified set are hidden.
    • To provide a custom implementation for a JSON:API endpoint in a partial class, the developer must include that endpoint in [Resource...] for it to show up. This enables to still write custom endpoints that throw, which shouldn't be listed.
  2. When using [Resource(GenerateControllerEndpoints = None)] or omitted at all, there may be a hand-written controller or not. So we can't determine what to hide. Code higher in the stack looks at the signature of action methods. If it is recognized as a JSON:API endpoint, it gets listed.
    • This means that hand-written controllers should only implement the endpoints it supports, for correct listing. This means deriving from BaseJsonApiController instead of JsonApiController and adding [HttpGet] etc on your action methods directly.

HttpRestrictAttribute was removed a long time ago, even before auto-generated controllers became available. I'm going to assume it was mentioned here by mistake.

Support for HttpHead was added after this issue was created, but it's a bit special. There's no flag for it in the JsonApiEndpoints enum. The Get* flags implicitly mean to also expose their HEAD equivalents. When setting the flags to None and providing a hand-written controller that derives from BaseJsonApiController with an action method that only has [HttpGet], you won't see the HEAD endpoint listed. But if you only add [HttpHead], it doesn't get listed at all. I suppose that's fine, because it doesn't make any sense to expose a HEAD endpoint without GET.

Non-standard action methods on JSON:API-controllers (for example, to upload a file) are out of scope. They remain hidden. The same applies for non-JSON:API controllers, and for atomic:operations controllers. Separate issues exist to address these.

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

No branches or pull requests

2 participants