DarkaOnLine / L5-Swagger

OpenApi or Swagger integration to Laravel
https://github.com/DarkaOnLine/L5-Swagger
MIT License
2.64k stars 394 forks source link

Hiding some endpoints #453

Closed marionfromfrance closed 2 years ago

marionfromfrance commented 2 years ago

Hi everybody,

I wrote all annotations for all my APIs, but would like to hide some of them. Is there a right way to do that? I saw a keyword @Hidden but didn't find implementation example...

Thanks a lot,

Marion

leonbtc1031 commented 2 years ago

Removing the documentation annotations above the function will hide it from the Swagger documentation.

marionfromfrance commented 2 years ago

Haha thank you I know that, but I would like to keep all the work, and not separate it from the methods. I guess a "hidden" or "disable" keyword would be useful to a lot of people.

leonbtc1031 commented 2 years ago

I couldn't find another option either.

marionfromfrance commented 2 years ago

Me neither, I tried to remove the @ or the OA, it seems to work at the first sight but when we open the generated json file it is inside generic components -_-

elythi0n commented 2 years ago

An alternative option would be to make a middleware and filter out the paths that you wish to hide.

In config/l5-swagger.php:

'middleware' => [
  'api' => [],
  'asset' => [],
  'docs' => [
      \App\Http\Middleware\ProcessOpenAPI::class
  ],
  'oauth2_callback' => [],
],

And the middleware:

/**
* Handle an incoming request.
*
* @param  \Illuminate\Http\Request  $request
* @param  \Closure  $next
* @return mixed
*/
public function handle($request, Closure $next)
{
  $content = json_decode(
      file_get_contents(
          storage_path() . '/api-docs/' . config('l5-swagger.documentations.default.paths.docs_json')
      , true)
  , true);

  $hide_paths = [
      '/api/path-to-hide'
  ];

  foreach($content['paths'] as $path => $methods) {
      if (in_array($path, $hide_paths)) {
          unset($content['paths'][$path]);
      }
  }

  return $content ? response()->json($content) : $next($request);
}

Downside to this is that you need to manually update the paths that you wish to hide. I would also make a separate configuration file for the paths you wish to hide.

Middleware for hiding certain methods:

/**
* Handle an incoming request.
*
* @param  \Illuminate\Http\Request  $request
* @param  \Closure  $next
* @return mixed
*/
public function handle($request, Closure $next)
{
  $content = json_decode(
      file_get_contents(
          storage_path() . '/api-docs/' . config('l5-swagger.documentations.default.paths.docs_json')
      , true)
  , true);

  $hide = [
      '/api/path-to-hide' => [
          'get',
          'post'
      ]
  ];

  foreach($content['paths'] as $path => $methods) {
      if (array_key_exists($path, $hide)) {
          foreach($methods as $method => $details) {    
              if (in_array($method, $hide[$path])) {
                  unset($content['paths'][$path][$method]);
              }
          }

          // this will remove the path if its empty after unsetting methods.
          if (empty($content['paths'][$path])) {
              unset($content['paths'][$path]);
          }
      }

  }

  return $content ? response()->json($content) : $next($request);
}
marionfromfrance commented 2 years ago

Hi, sounds great I'll try your solution, thank you!