1

I've generated rest api with openAPI generator maven plugin and I've overridden the default method from MyApiDelegate interface, but POST request on /endpoint provides 501 NOT IMPLEMENTED as if I hadn't given my own implementation of that method in MyApiDelegateImpl.

Maven plugin configuration:

<plugin>
                <groupId>org.openapitools</groupId>
                <artifactId>openapi-generator-maven-plugin</artifactId>
                <version>4.3.1</version>
                <executions>
                    <execution>
                        <goals>
                            <goal>generate</goal>
                        </goals>
                        <configuration>
                            <configOptions>
   <inputSpec>${project.basedir}/src/main/resources/latest.yaml</inputSpec>
                            <generatorName>spring</generatorName>
                            <apiPackage>my.rest.api</apiPackage>
                            <modelPackage>my.rest.model</modelPackage>
                       <supportingFilesToGenerate>ApiUtil.java</supportingFilesToGenerate>
                                <delegatePattern>true</delegatePattern>
                                <useBeanValidation>false</useBeanValidation>
                            </configOptions>
                        </configuration>
                    </execution>
                </executions>
</plugin>
/* code generated by plugin */
package my.rest;
public interface MyApiDelegate {
    default Optional<NativeWebRequest> getRequest() {
        return Optional.empty();
    }

    default ResponseEntity<Void> doSmth(Smth smth) {
        return new ResponseEntity<>(HttpStatus.NOT_IMPLEMENTED);
    }

}

package my.rest.api;
public interface MyApi {
    default MyApiDelegate getDelegate() {
        return new MyApiDelegate() {};
    }

    /*...Api operations annotations...*/
    @RequestMapping(value = "/endpoint",
        produces = { "application/json" }, 
        consumes = { "application/json", "application/xml" },
        method = RequestMethod.POST)
    default ResponseEntity<Void> doSmth(@ApiParam(value = "" ,required=true) @RequestBody Smth smth) {
        return getDelegate().doSmth(smth);
    }

}

my implementation:

package my.rest.api;
@Service
@RequiredArgsConstructor
public class MyApiDelegateImpl implements MyApiDelegate {
    private final MyService s;

    @Override
    public ResponseEntity<Void> doSmth(Smth smth) {
        s.doIt(smth);
        return ResponseEntity.ok().build();
    }
}

How can I make my program use my own implementation of the method in concrete class, not the default implementation, which is provided in interface?

obolen_an
  • 41
  • 6

1 Answers1

1

Implementing the MyApi interface directly and hence the method doSmth in it, is one way of doing that. Your concrete class need not have all the web related annotations but just the paramters and return value like a normal method.

I don't understand how can an interface MyApiDelegate can be initialized but since getDelegate returns an implementation of it, the default implementation of doSmth is called which returns HttpStatus.NOT_IMPLEMENTED.

One more thing to take care of is making sure the deployment knows to use the implementation class. If you're using spring web than just marking your concrete class @RestController should suffice.

Akshay
  • 158
  • 1
  • 7
  • since openAPI generator uses Delegate DP, the purpose of the default method in MyApi interface is just to call the appropriate service, thus it does not solve my problem. Due to openAPI generator plugin annotation Controller is enough. The thing I really don't understand is why my class uses the default implementation in the interface even though I've created a concrete class with a method that overrides it. – obolen_an Oct 24 '21 at 12:55