phoenixnap / springmvc-raml-plugin

Spring MVC - RAML Spec Synchroniser Plugin. A Maven plugin designed to Generate Server & Client code in Spring from a RAML API descriptor and conversely, a RAML API document from the SpringMVC Server implementation.
Apache License 2.0
136 stars 84 forks source link

Requests and Responses with Multiple Types with different MediaType are not supported #299

Open techpavan opened 5 years ago

techpavan commented 5 years ago

Provided below is a RAML which is valid and parsed well by other tools. But when we try to generate Java code, it fails with the exception provided at the bottom. The below method could be represented in the controller as public Single<ResponseEntity<?>> createMessage(Object object, HttpHeaders httpHeaders) where the implementer owns the responsibility on how to respond.

If the below RAML is slightly changed by removing the request body and support multiple response types, only the first one gets picked for code generation and that too is incorrect.

Please see if these could be handled better.

Reproducer: https://github.com/techpavan/springmvc-raml-plugin-issues/tree/master/2

#%RAML 1.0
title: MessageServer

types:
  Email:
    type: object
    properties:
      subject: string
      body: string
  Sms:
    type: object
    properties:
      content: string

/messages:
  post:
    body:
      application/json:
        type: Email
      applicationV2/json:
        type: Sms
    responses:
      200:
        body:
          application/json:
            type: Email
          applicationV2/json:
            type: Sms

Exception thrown:

Caused by: java.lang.IllegalStateException: Body Metadata is immutable
    at com.phoenixnap.oss.ramlplugin.raml2code.data.ApiActionMetadata.setRequestBody (ApiActionMetadata.java:350)
    at com.phoenixnap.oss.ramlplugin.raml2code.data.ApiActionMetadata.collectBodyParams (ApiActionMetadata.java:173)
    at com.phoenixnap.oss.ramlplugin.raml2code.data.ApiActionMetadata.parseRequest (ApiActionMetadata.java:134)
    at com.phoenixnap.oss.ramlplugin.raml2code.data.ApiActionMetadata.<init> (ApiActionMetadata.java:77)
    at com.phoenixnap.oss.ramlplugin.raml2code.data.ApiResourceMetadata.addApiCall (ApiResourceMetadata.java:55)
    at com.phoenixnap.oss.ramlplugin.raml2code.helpers.RamlParser.checkResource (RamlParser.java:167)
    at com.phoenixnap.oss.ramlplugin.raml2code.helpers.RamlParser.extractControllers (RamlParser.java:77)
    at com.phoenixnap.oss.ramlplugin.raml2code.plugin.SpringMvcEndpointGeneratorMojo.generateEndpoints (SpringMvcEndpointGeneratorMojo.java:284)
    at com.phoenixnap.oss.ramlplugin.raml2code.plugin.SpringMvcEndpointGeneratorMojo.execute (SpringMvcEndpointGeneratorMojo.java:527)
stojsavljevic commented 5 years ago

Yeah, multiple request's media types are not supported. That's why I'm marking this as an enhancement.

Unfortunately, supporting this is not going to be very easy. We should be generating one method for every media type of request. In your example, we should generate a method that receives Email and another for Sms. This should be done for all rules.

Can you please consider a PR?

techpavan commented 5 years ago

Not sure if I can find time to take a deep dive and come up with PR in my current occupancy. But do share some hints on classes and methods that are closely involved and I can try to see if I could attempt.