looking at: https://www.drupal.org/project/openapi/issues/2894623, suggested a way to add description to parameters.
Resources are expected to implement getPluginDefinition with 're_annotation' of the resource parameters.

public function getPluginDefinition() {
    return NestedArray::mergeDeep(
      parent::getPluginDefinition(),
      ['re_annotation' => [
        "GET" => [
          "id" => 'ID of the resource',
        ],
        "PUT" => [
          "id" => 'An array with the payload',
        ],
      ]]
    );
  }
Command icon Show commands

Start within a Git clone of the project using the version control instructions.

Or, if you do not have SSH keys set up on git.drupalcode.org:

Comments

alianov created an issue. See original summary.

alianov’s picture

StatusFileSize
new3.8 KB
alianov’s picture

StatusFileSize
new2.99 KB
alianov’s picture

alianov’s picture

StatusFileSize
new3.18 KB

extending parameter description as per OpenAPI Specification.

expecting resources to implement

public function getPluginDefinition() {
    return NestedArray::mergeDeep(
      parent::getPluginDefinition(),
      ['openapi' => [
        "GET" => [
          "id" => ['name' => 'id', 'description' => 'parameter description', 'type' => 'string', 'in' => 'path', 'required' => true],
        ],
      ]]
    );
  }
marco-s’s picture

StatusFileSize
new3.97 KB
new3.3 KB

Thanks for the patch alianov!
I would recommend to name the array key 'parameters' instead of 'openapi'.
I have also optimized your patch a bit.

Example usage:

public function getPluginDefinition() {
  return NestedArray::mergeDeep(
    parent::getPluginDefinition(),
    [
      'parameters' => [
        'POST' => [
          'entityType' => [
            'name' => 'entityType',
            'description' => 'The entity type name.',
            'type' => 'string',
            'in' => 'path',
            'required' => TRUE,
          ],
        ],
        'DELETE' => [
          'entityType' => [
            'name' => 'entityType',
            'description' => 'The entity type name.',
            'type' => 'string',
            'in' => 'path',
            'required' => TRUE,
          ],
        ],
      ],
    ]
  );
}
marco-s’s picture

StatusFileSize
new4.81 KB
new2.52 KB

I added a payload option. Also I renamed the array key from 'parameters' to 'route_parameters', because they are only for the route parameters (resp. 'in' => 'path').

Example usage:

public function getPluginDefinition() {
  $definition = parent::getPluginDefinition();
  // Note: Since there can only be one payload, there can only be one body parameter.
  $definition['payload'] = [
    'name' => 'body',
    'description' => 'The payload',
    'in' => 'body',
    'required' => TRUE,
    'schema' => [
      'type' => 'object',
      'properties' => [
        'username' => [
          'type' => 'string',
          'example' => 'test-username',
        ],
      ],
    ],
  ];
  $definition['route_parameters'] = [
    'POST' => [
      'entityType' => [
        'name' => 'entityType',
        'description' => 'The entity type name.',
        'type' => 'string',
        'in' => 'path',
        'required' => TRUE,
      ],
    ],
    'DELETE' => [
      'entityType' => [
        'name' => 'entityType',
        'description' => 'The entity type name.',
        'type' => 'string',
        'in' => 'path',
        'required' => TRUE,
      ],
    ],
  ];

  return $definition;
}
kevinvb’s picture

Hi,

It's nice to see the work already done for this so describing parameters is possible.
I do had however one use case which wasn't covered yet (could be I'm just missing documentation) but my rest resource can handle a offset query parameter.
To make sure modules like swagger_ui can handle those parameters and display them in the documentation I've added a small functionality to this generator.

Example usage:
Use 'query_params' in your rest resource.

  /**
   * {@inheritDoc}
   */
  public function getBaseRoute($canonical_path, $method) {
    $route = parent::getBaseRoute($canonical_path, $method);
    $route->setOption('query_params', [
      [
        'name' => 'offset',
        'in' => 'query',
        'type' => 'integer',
        'required' => FALSE,
        'description' => 'The page numbering, each page returns 25 items.',
      ],
    ]);
    return $route;
  }
kevinvb’s picture

Added simple is_array check around the extra query_params option so rest resources with paths not having any query arguments described won't throw warnings.

kevinvb’s picture

StatusFileSize
new4.94 KB

And now with a working patch, sorry.

kasperg’s picture

I agree with #8 that the implementation in #7 does not support query parameters. However I did not like the implementation in #10 which adds a new way to specify query parameters in getBaseRoute() compared to the original implementation which does the work in the plugin definition and thus also support defining parameters in the @RestResource annotation.

I have attached an alternate approach to adding support for query parameters which is based on the work in #7. Sorry, no interdiff. For some reason it is not working.

Example usage:

public function getPluginDefinition() {
  $definition = parent::getPluginDefinition();
  // Note: Since there can only be one payload, there can only be one body parameter.
  $definition['payload'] = [
    'name' => 'body',
    'description' => 'The payload',
    'in' => 'body',
    'required' => TRUE,
    'schema' => [
      'type' => 'object',
      'properties' => [
        'username' => [
          'type' => 'string',
          'example' => 'test-username',
        ],
      ],
    ],
  ];
  $definition['route_parameters'] = [
    'POST' => [
      'entityType' => [
        'name' => 'entityType',
        'description' => 'The entity type name.',
        'type' => 'string',
        'in' => 'path',
        'required' => TRUE,
      ],
    ],
    'DELETE' => [
      'entityType' => [
        'name' => 'entityType',
        'description' => 'The entity type name.',
        'type' => 'string',
        'in' => 'path',
        'required' => TRUE,
      ],
    ],
    'GET' => [
      'offset' => [
        'name' => 'offset',
        'description' => 'The page numbering, each page returns 25 items.',
        'type' => 'integer',
        'in' => 'query',
        'required' => FALSE,
      ],
    ],
  ];

  return $definition;
}
kasperg’s picture

StatusFileSize
new5.22 KB

The patch in #11 produces an invalid specification as parameters for a path must be an array. With the patch in #11 it can become an object an object when using strings for keys e.g. with offset in the example above.

The updated patch strips the keys.

kasperg’s picture

Status: Active » Needs review
kasperg’s picture

StatusFileSize
new5.23 KB

The patch in #12 fails if there are no route parameters defined. Here is an updated patch which fixes that.

grathbone’s picture

StatusFileSize
new7.74 KB

The Payload functionality doesn't work when it comes to different payloads per method. Modified the payload functionality to accept a nested method.

anybody’s picture

Status: Needs review » Needs work

I think this should use MRs instead to make it easier for maintainers to review and merge.

immaculatexavier made their first commit to this issue’s fork.

immaculatexavier’s picture

Status: Needs work » Needs review
jeffschuler’s picture

Status: Needs review » Needs work

I struggled for awhile trying to figure out how to specify that a param for a custom REST resource should be in the query.

I was able to do so using the patch from #15. (#14 worked for my purposes too.)

After applying the patch, I modified my @RestResource annotation to include the info about the query param like this:

/**
 * Provides a REST resource.
 *
 * @RestResource(
 *   id = "my_rest_resource",
 *   label = @Translation("My REST Reource"),
 *   uri_paths = {
 *     "create" = "/api/v1/foo/{path_param_1}/bar/{path_param_2}"
 *   },
 *   route_parameters = {
 *     "POST" = {
 *       "my_query_param" = {
 *         "name" = "my_query_param",
 *         "in" = "query",
 *         "type" = "string",
 *         "description" = "My custom query param in addition to the path params",
 *         "required" = true,
 *       }
 *     }
 *   }
 * )
 */

Setting status to Needs work for somebody to take @anybody's advice in turning this into a MR.

jeffschuler’s picture

Status: Needs work » Needs review

Sorry @immaculatexavier!
I totally missed that you had already made this a MR. :-p

jeffschuler’s picture

MR !8 is working as well for my purpose of defining a query-based endpoint param.