tminglei / binder-swagger-java

A framework to bring form-binder-java to swagger
BSD 2-Clause "Simplified" License
54 stars 13 forks source link

Add support for structured examples #3

Closed momania closed 7 years ago

momania commented 7 years ago

Examples can only be provided as text, but in case of a json structure, this gets wrongly put in quotes, escaped and won't render properly in the Swagger UI (plus clicking an example doesn't put the right data in the 'Try now' section.

Perhaps add a utility method like:

$(mapping(
// .....
  )).rawExample(jsonContentAsString).$$

And then don't apply any sanitisation on it?

tminglei commented 7 years ago

Hi @momania a better place to put structured examples is model definition or property's example property, which you can associate real example object with.

For parameter's example, which will json out as x-example, seems to be restrict to simple string specially.

momania commented 7 years ago

Ok, maybe I should explain with a small example. Say I have this simple class and a sample for it:

case class Quote(bid: Double, ask: Double)
val quoteExample = Quote(99.0, 100.0)

Then either on my definition or on the response object, I want to add this example. On the response object you have to do this together with the mime-type but the result of the example on both response object or model definition is the same.

When I do:

response(quote).example("application/json", quoteExample)

the output is:

"examples": {
  "application/json":  {}
}

When I serialize it myself to a json string I get this:

"examples": {
  "application/json": "{\"bid\":99.0,\"ask\":100.0}"
}

But what I want is:

"examples": {
  "application/json": {
    "bid": 99.0,
    "ask": 100.0
  }
}

which is also how it should be according to the specs: http://swagger.io/specification/#exampleObject

tminglei commented 7 years ago

But, when I defined:

    static class Example {
        public final long id;
        public final String name;

        Example(long id, String name) {
            this.id = id;
            this.name = name;
        }
    }

Use it like this:

response(pet).example("test", new Example(1L, "test"))

I got output:

{
  "test": {
    "id": 1,
    "name": "test"
  }
}

I use Java, and binder-swagger-java uses jackson json.

Maybe I should implement a scala version of this framework.

momania commented 7 years ago

Aaah, got it, my bad. When I put explicit BeanProperty annotations on the case class properties it works as expected.

A small scala wrapper around this would be nice yes. 😃

[edit] Although in general the default translation doesn't really go well, especially when you use scala specific properties that are wrapped in an Option, or when you use things like JodaTime, then the output becomes even crazier:

"myTimestamp": {
  "era": 1,
  "dayOfYear": 278,
  "dayOfWeek": 2,  
  "dayOfMonth": 4,
  "year": 2016,
  "weekOfWeekyear": 40,
  "millisOfDay": 34746192,
  "monthOfYear": 10,
  "hourOfDay": 9,
  "minuteOfHour": 39,
  "secondOfMinute": 6,
  "millisOfSecond": 192,
  "weekyear": 2016,
  "yearOfEra": 2016,
  "yearOfCentury": 16,
  "centuryOfEra": 20,
  "secondOfDay": 34746,
  "minuteOfDay": 579,
  "zone": {
    "fixed": true,
    "id": "UTC"
  },
  "millis": 1475573946192,
  "chronology": {
    "zone": {
      "fixed": true,
      "id": "UTC"
    }
  },
  "afterNow": false,
  "beforeNow": true,
  "equalNow": false
}
tminglei commented 7 years ago

Glad to hear that. :-)