[JAVA][jaxrs] codegen with tags uses wrong @Path values

Open
#7,767 6 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Assessment

Difficulty
3/5
Estimated time
1-2 days
Newbie friendliness
45/100
Issue type
Bug
Clarity
Clearly specified
Activity status
Stale
Tech stack
java
Domain
tooling

Research direction

Start in JavaJerseyServerCodegen.addOperationToGroup() and compare the useTags=true fallback to DefaultCodegen with the useTags=false path handling. Regenerate the supplied YAML using the shown CLI command and verify that tagged Api classes retain the operation paths in @Path annotations, with matching @PathParam values.

Written by the indexing model from the issue text.

Description

Description

When creating jaxrs server stubs with useTags=true the Api classes have a wrong value for the @Path annotation. They contain the tag value (camel case) but not the path defined in the YAML file. When I omit useTags=true, then the @Path annotation contains the correct value but the Api class names are automatically generated (in not useful in my case).

Swagger-codegen version

2.3.1

Swagger declaration file
swagger: "2.0"
info:
  description: "Test REST API"
  version: "1.0.0"
  title: "Test"
host: "localhost"
basePath: "/v1"
schemes:
- "https"

tags:
- name: "document"

paths:
  /{userId}/documents:
    parameters:
    - name: "userId"
      in: "path"
      required: true
      type: "integer"
      format: "int64"

    get:
      tags:
      - "document"
      operationId: "getDocumentList"
      produces:
      - "application/json"
      responses:
        200:
          schema:
            type: "array"
            items:
              $ref: "#/definitions/DocumentListItem"

    post:
      tags:
        - "document"
      operationId: "createDocument"
      consumes:
      - "application/json"
      produces:
      - "application/json"
      parameters:
      - in: "body"
        name: "document"
        required: true
        schema:
          $ref: "#/definitions/Document"
      responses:
        200:
          schema:
            $ref: "#/definitions/Document"

  /{userId}/documents/{documentId}:
    parameters:
    - name: "userId"
      in: "path"
      required: true
      type: "integer"
      format: "int64"
    - name: "documentId"
      in: "path"
      required: true
      type: "string"

    get:
      tags:
        - "document"
      operationId: "getDocument"
      produces:
      - "application/json"
      responses:
        200:
          schema:
            $ref: "#/definitions/Document"
            
    put:
      tags:
        - "document"
      operationId: "updateDocument"
      consumes:
      - "application/json"
      produces:
      - "application/json"
      parameters:
      - in: "body"
        name: "document"
        required: true
        schema:
          $ref: "#/definitions/Document"
      responses:
        200:
          schema:
            $ref: "#/definitions/Document"
            
    delete:
      tags:
        - "document"
      operationId: "deleteDocument"
      produces:
      - "application/json"
      responses:
        204
      

definitions:

  DocumentListItem:
    type: "object"
    properties:
      id:
        type: "string"
      name:
        type: "string"

  Document:
    type: "object"
    properties:
      id:
        type: "string"
      name:
        type: "string"
Configuration file
{
	"java8": true,
	"dateLibrary": "java8",
	"useTags": true
}
Command line used for generation

java -jar swagger-codegen-cli-2.3.1.jar generate -l jaxrs -i test-api.yaml -c test-config.json

Generated Api class
@Path("/Document")
public class DocumentApi  {

    @POST
    public Response createDocument(@PathParam("userId") Long userId, Document document, ) {
        ...
    }

    @DELETE
    public Response deleteDocument(@PathParam("userId") Long userId, @PathParam("documentId") String documentId) {
        ...
    }

    @GET
    public Response getDocument(@PathParam("userId") Long userId, @PathParam("documentId") String documentId) {
        ...
    }

    @GET
    public Response getDocumentList(@PathParam("userId") Long userId) {
        ...
    }

    @PUT
    public Response updateDocument(@PathParam("userId") Long userId, @PathParam("documentId") String documentId, Document document) {
        ...
    }
}

Code shortened for readability. Only have a look at @Path and @PathParam.

As you can see, the class has the @Path annotation value "/Document" instead of "/{userId}/documents". The methods itself have no @Path annotation at all. The @PathParam annotations for userId and documentId are never defined within a @Path annotation. This is not valid with JaxRS.

Suggest a fix/enhancement

In JavaJerseyServerCodegen.addOperationToGroup() the code falls back to DefaultCodegen.addOperationToGroup() when useTags=true. And there the paths of the operations are not correctly handled.

    public void addOperationToGroup(String tag, String resourcePath, Operation operation, CodegenOperation co, Map<String, List<CodegenOperation>> operations) {
        if (useTags) {
            super.addOperationToGroup(tag, resourcePath, operation, co, operations);
        } else  {
            ...
        }
    }

Probably there should be a dedicated implementation instead of falling back to DefaultCodegen. The correct code might be nearly identical to the case when useTags=false but the name for the Api class have to match the tag name.

Dominant language
Mustache
Stars
17.8k
Forks
6k
PR merge metrics
No merged PRs in 30d

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

More from swagger-api/swagger-codegen

All issues in swagger-api/swagger-codegen

Similar issues

More DevTools issues

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.