swagger codegen is overwriting my custom code in generated files

后端 未结 3 1550
死守一世寂寞
死守一世寂寞 2021-02-05 20:31

I used the swagger codegen to generate jaxrs server side classes and also client side java classes.

This is the command I used to generate the classes

ja         


        
相关标签:
3条回答
  • 2021-02-05 21:02

    The latest master of Swagger Codegen allows you to specify files not to be overwritten in .swagger-codegen-ignore (similar to .gitignore) during code generation.

    Please pull the latest master of Swagger Codegen to give it a try.

    UPDATE: On May 2018, about 50 top contributors and template creators of Swagger Codegen decided to fork Swagger Codegen to maintain a community-driven version called OpenAPI Generator. Please refer to the Q&A for more information.

    0 讨论(0)
  • 2021-02-05 21:11


    Hello,
    maybe after four years the answer comes a little bit late, but better late instead of never.

    If you have a right swagger file (not only a fragment) like the following

    openapi: "3.0.0"
    :
    paths:
      /example:
        get:
          operationId: showIt
    :
    

    and you run a code generation, in this explanation for a jaxs-jersey-server without any code generaction specific configuration values (which you can download from the Swagger editor), you get a bulk of java clases like the following:

    io.swagger.api.          ExampleApi
    io.swagger.api.          ExampleApiService
    io.swagger.api.factories.ExampleApiServicefactory
    io.swagger.api.impl.     ExampleApiServiceImpl
    

    In the REST endpoint implementation ExampleApiServiceImpl you see more or less something like the following:

    package io.swagger.api.impl;
    
    :
    import ... ;
    :
    
    @javax.annotation.Generated(...)
    public
    class   ExampleApiServiceImpl
    extends ExampleApiService
    {
        // ...
        @Override
        public
        Response showIt( /* additional parameters , */ SecurityContext securityContext)
        throws NotFoundException
        {
            // do some magic!
            return Response.ok()
                           .entity(new ApiResponseMessage( ApiResponseMessage.OK
                                                         , "magic!"
                                                         )
                                  )
                           .build();
        }
        // ...
    }
    

    Do you now exchange the magic comment

            // do some magic!
    

    through maybe the following

            String className = this.getClass().getSimpleName();
            System.out.println("Entered REST endpoint: path=|" + className.substring(0, className.length() - 14) + "| operationId=|showId|");
    

    you should see a log message if you call the endpoint from your browser after you have done a mvn clean package jetty:run. But that's not a good idea, as you realized, because after the next generation, your change is gone.

    In this context, it is never a good idea to change generated code manually, because this MUST be then so well documented that a future colleague (that could after a few months or years even be you) even in halfsleep on Sundays of Monday night makes the changes again after the next code generation. But my more than 20 years of experience with different code generators says only one thing about this: Forget it! For the same reason, it is not really goal-oriented to prevent further generation after the first generation, because this too has to be documented extensively. Otherwise debugging hour over debugging hour could come up with troubleshooting why the new feature does not work.

    But that is all not necessary.
    In the generated class io.swagger.api.ExampleApi you would find a constructor like the following (Ok, that is the state of 2019-05-17. I don't know if it was the same (or similar) four years ago)

    package io.swagger.api;
    
    :
    import ... ;
    :
    
    @Path("/example")
    
    @javax.annotation.Generated(...)
    public class ExampleApi
    {
       private final ExampleApiService delegate;
    
       public ExampleApi(@Context ServletConfig servletContext)
       {
          // ...
          if (servletContext != null) {
             String implClass = servletContext.getInitParameter("ExampleApi.implementation");
             if (implClass != null && !"".equals(implClass.trim()))
             {
                try
                {
                   delegate = (ExampleApiService) Class.forName(implClass).newInstance();
                }
                catch (Exception e)
                {
                   throw new RuntimeException(e);
                }
             } 
          }
          // ...
        }
    // ...
    }
    

    The importand piece of code is the servletContext.getInitParameter("..."). If you now specify in the servlet configuration a key with the the name ExampleApi.implementation with an full qualified java classname which is derived from ExampleApiService you have implemented your own endpoint code which is secure for overwriting throught future code generations.

    For finishing the example, this specification would made in the (additional generated, oouuch, sorry, you can not have everything) web.xml file. This file contains something like:

        <servlet>
            <servlet-name>jersey</servlet-name>
            <servlet-class>org.glassfish.jersey.servlet.ServletContainer</servlet-class>
            ...
            <load-on-startup>1</load-on-startup>
        </servlet>
    

    In this xml fragment you have to insert after the periods (which stand for other servlet configuration settings) the following:

            <init-param>
                <param-name>ExampleApi.implementation</param-name>
                <param-value>my.swagger.api.MyExample</param-value>
            </init-param>
    

    Good look,
    whatever you currently are!

    0 讨论(0)
  • 2021-02-05 21:13

    You can specify the files you want to ignore in .swagger-codegen-ignore file

    Here is the sample self explainatory auto-generated code for .swagger-codegen-ignore file

    # Swagger Codegen Ignore
    # Generated by swagger-codegen https://github.com/swagger-api/swagger-codegen
    
    # Use this file to prevent files from being overwritten by the generator.
    # The patterns follow closely to .gitignore or .dockerignore.
    
    # As an example, the C# client generator defines ApiClient.cs.
    # You can make changes and tell Swagger Codgen to ignore just this file by uncommenting the following line:
    #ApiClient.cs
    
    # You can match any string of characters against a directory, file or extension with a single asterisk (*):
    #foo/*/qux
    # The above matches foo/bar/qux and foo/baz/qux, but not foo/bar/baz/qux
    
    # You can recursively match patterns against a directory, file or extension with a double asterisk (**):
    #foo/**/qux
    # This matches foo/bar/qux, foo/baz/qux, and foo/bar/baz/qux
    
    # You can also negate patterns with an exclamation (!).
    # For example, you can ignore all files in a docs folder with the file extension .md:
    #docs/*.md
    # Then explicitly reverse the ignore rule for a single file:
    #!docs/README.md
    

    You can add some lines below this to ignore e.g. I want to ignore all file in folder impl so I added the following line to do that

    **/impl/*
    
    0 讨论(0)
提交回复
热议问题