I'm trying to display some formatted text in a YAML file (in the example: key):
log_level_per_component:
type: object
example:
"{
\"Component1\": \"Info\",\n
\"Component2\": \"Debug\",\n
\"Component3\": \"Fatal\",\n
...\n
}"
for getting such a Swagger output:
"log_level_per_component": "{
"Component1": "Info",n
"Component2": "Debug",n
"Component3": "Fatal",n
...
}"
but I always get this:
"log_level_per_component": "{ \"Component1\": \"Info\",\n \"Component2\":
\"Debug\",\n \"Component3\": \"Fatal\",\n ...\n }"
Any idea what I can do to fix it?
Update 2018-05-17 for Helen's screenshot request about her solution:
This is what I get with both solutions by using "example:":
And this what I get by using "examples:":
Both are always empty.
YAML is a superset of JSON, so you can use the normal JSON object literal syntax in YAML:
log_level_per_component:
type: object
example:
{
"Component1": "Info",
"Component2": "Debug",
"Component3": "Fatal"
}
Alternatively, you can use YAML object syntax, and Swagger UI will render the example as JSON (provided that your request or response type is JSON):
log_level_per_component:
type: object
example:
Component1: Info
Component2: Debug
Component3: Fatal
Related
Looking at the documentation here https://serverless.com/framework/docs/providers/aws/events/apigateway/#custom-response-templates, there doesn't seem to be much detail at all about setting up these templates.
I'm currently looking to remove the default application/json content-type, which is generated during creation of the handler's integration response (pictured below), and replace it with text/html. Is there defined syntax for how to do this hidden somewhere? Or is this level of customization not possible within the current scope of the framework?
Here is my endpoint as defined in serverless.yml
events:
- http:
method: any
path: /
integration: lambda
request:
region: ${env:AwsRegion}
response:
headers:
Content-Type: "'text/html'"
template: $input.path('body')
- http:
method: any
path: /{proxy+}
Which produces the following configuration on AWS Api Gateway:
I did try modifying the specification like this, as a guess, but it threw a syntax error:
template:
text\html: $input.path('body')
Make It Work
It looks like this isn't really supported by the framework, but it can be hacked together by (ab)using statusCodes in your serverless template.
Moving the response template to under a status code, and providing a pattern for that status code, accomplishes what I think you are after. The syntax:
- http:
method: any
path: /
integration: lambda
request:
region: us-east-1
response:
headers:
Content-Type: "'text/html'"
statusCodes:
200:
pattern: ""
template:
text/html: $input.path('body')
Note: Both the pattern and the template must be present.
Is It Really That Bad?
That's up to you, ultimately. I'm calling it a hack because:
It would be much nicer to be able to supply this at the response.template level, rather than at response.statusCodes.200.template.
Specifying one or more statusCodes removes the set of default lambda error regexes that you get when you don't specify any.
It feels like working around the fact that response.template will only accept a string, whereas it could (should?) accept a string or an object (like it does under statusCodes).
Fix It?
The offending code, from /lib/plugins/aws/package/compile/events/apiGateway/lib/method/integration.js:
if (http.response.template) {
_.merge(integrationResponse.ResponseTemplates, {
'application/json': http.response.template,
});
}
if (config.template) {
const template =
typeof config.template === 'string'
? { 'application/json': config.template }
: config.template;
_.merge(integrationResponse.ResponseTemplates, template);
}
I think for this to work under response.template, the code in the first if() would need to behave more like the code in the second if().
In swagger's documentation using OpenApi specification, you can wrap schema in parameter to content with application/json:
parameters:
- in: query
name: filter
# Wrap 'schema' into 'content.<media-type>'
content:
application/json: # <---- media type indicates how to serialize / deserialize the parameter content
schema:
type: object
properties:
type:
type: string
color:
type: string
to send objects like this filter={"type":"t-shirt","color":"blue"}.
How to do it in swagger-php?
The swagger-editor and swagger-ui have added support for http://swagger.io/docs/specification/describing-parameters
The swagger-php library has added support too, it will be part of the 3.0.4 release.
I define endpoints with Swagger file, and for one of the endpoints the body (a JSON) is not required.
I describe it in this way in the yaml file:
- in: "body"
name: "body"
description: "some description here..."
required: false
schema:
type: string
After that I generate code from the Swagger file and for the body I get the following description in the method for this endpoint in the generated class:
#Valid #RequestBody String body
the generated file is an interface, and when I implement the method, and call the endpoint without setting a body, I get:
Resolved [org.springframework.http.converter.HttpMessageNotReadableException: Required request body is missing:
Can somebody tell me what I am doing wrong? When I put
#RequestBody(required=false) String body
, then everything works correct, but I would like this (required=false) to be generated automatically from the code generator...
I used the CSV format for the data files in JMeter. Our VP wants to change the format to JSON. How can I read a JSON file from the disk?
You have at least 2 options:
Use HTTP Request sampler and file protocol like:
JSON files are basically plain-text files so you will be able to use JSON Extractor or JSON Path Extractor to parse JSON data and store the result into JMeter Variables for later reuse
References:
Jayway JsonPath - Getting Started
Advanced Usage of the JSON Path Extractor in JMeter
Use JSR223 Test Elements and Groovy language. Groovy has built-in JSON support via JsonSlurper so you will be able to parse the JSON file programmatically.
References:
The Groovy programming language - Parsing and producing JSON
Groovy - JSON
The best solution for this problem is to use JSR223 Sampler to read JSON file and load into the vars or props and use it wherever it is required.
For this,
Add a JSR223 Sampler in JMeter
Add the below code
import java.io.File
import java.util.Base64
def propertiesFromMap(map, prefix) {
for (item in map) {
id = prefix+item.key;
if (item.value instanceof Map) {
propertiesFromMap(item.value, id+".");
} else {
value = item.value.toString();
log.info("Loading property " + id + ": " + value);
if(value.startsWith("ENC:")) {
props.put(id, new String(Base64.getDecoder().decode(value.substring(4, value.length()))));
} else {
props.put(id, value);
}
}
}
}
def baseDir = org.apache.jmeter.services.FileServer.getFileServer().getBaseDir();
def jsonFilePath= baseDir + "/configs/" + "configuration-dev" + ".json";
log.info("Loading properties from " + jsonFilePath);
def jsonMap = new groovy.json.JsonSlurper().parse(new java.io.File(jsonFilePath));
propertiesFromMap(jsonMap, '');
Create a directory named configs where you placed the .jmx file
Create a file named configuration-dev.json in configs directory
Add JSON content e.g. in the file:
{
"key1": "value1",
"key2": "value2",
"key3": "ENC:base64_encoded_value"
"group1": {
"grp1_key": "value"
}
Access values in Samplers e.g. ${__P(key1)}, it will return value of key1. For group1 variables access e.g. ${__P(group1.grp1_key)}
For accessing the values into JSR223 use props e.g. props.get("key1")
You can pass base64 encoded values into JSON by adding ENC: as value prefix which will be resolved automatically when accessing values from props or __P()
I am trying to integrate Spring REST docs with rest assured with Grails 3.1.4 application. I am using JSON Views.
Complete code is at https://github.com/rohitpal99/rest-docs
In NoteController when I use
List<Note> noteList = Note.findAll()
Map response = [totalCount: noteList.size(), type: "note"]
render response as grails.converters.JSON
Document generation works well.
But I want to use JSON views like
respond Note.findAll()
where I have _notes.gson and index.gson files in /views directory. I get a SnippetException. A usual /notes GET request response is correct.
rest.docs.ApiDocumentationSpec > test and document get request for /index FAILED
org.springframework.restdocs.snippet.SnippetException at ApiDocumentationSpec.groovy:54
with no message. Unable to track why it occurs.
Please suggest.
Full stacktrace
org.springframework.restdocs.snippet.SnippetException: The following parts of the payload were not documented:
{
"instanceList" : [ {
"title" : "Hello, World!",
"body" : "Integration Test from Hello"
}, {
"title" : "Hello, Grails",
"body" : "Integration Test from Grails"
} ]
}
at org.springframework.restdocs.payload.AbstractFieldsSnippet.validateFieldDocumentation(AbstractFieldsSnippet.java:134)
at org.springframework.restdocs.payload.AbstractFieldsSnippet.createModel(AbstractFieldsSnippet.java:74)
at org.springframework.restdocs.snippet.TemplatedSnippet.document(TemplatedSnippet.java:64)
at org.springframework.restdocs.generate.RestDocumentationGenerator.handle(RestDocumentationGenerator.java:192)
at org.springframework.restdocs.restassured.RestDocumentationFilter.filter(RestDocumentationFilter.java:63)
at com.jayway.restassured.internal.filter.FilterContextImpl.next(FilterContextImpl.groovy:73)
at org.springframework.restdocs.restassured.RestAssuredRestDocumentationConfigurer.filter(RestAssuredRestDocumentationConfigurer.java:65)
at com.jayway.restassured.internal.filter.FilterContextImpl.next(FilterContextImpl.groovy:73)
at com.jayway.restassured.internal.RequestSpecificationImpl.applyPathParamsAndSendRequest(RequestSpecificationImpl.groovy:1574)
at com.jayway.restassured.internal.RequestSpecificationImpl.get(RequestSpecificationImpl.groovy:159)
at rest.docs.ApiDocumentationSpec.$tt__$spock_feature_0_0(ApiDocumentationSpec.groovy:54)
at rest.docs.ApiDocumentationSpec.test and document get request for /index_closure2(ApiDocumentationSpec.groovy)
at groovy.lang.Closure.call(Closure.java:426)
at groovy.lang.Closure.call(Closure.java:442)
at grails.transaction.GrailsTransactionTemplate$1.doInTransaction(GrailsTransactionTemplate.groovy:70)
at org.springframework.transaction.support.TransactionTemplate.execute(TransactionTemplate.java:133)
at grails.transaction.GrailsTransactionTemplate.executeAndRollback(GrailsTransactionTemplate.groovy:67)
at rest.docs.ApiDocumentationSpec.test and document get request for /index(ApiDocumentationSpec.groovy)
REST Docs will fail a test if you try to document something that isn't there or fail to document something that is there. You've documented two fields in your test:
responseFields(
fieldWithPath('totalCount').description('Total count'),
fieldWithPath('type').description("Type of result")
)))
REST Docs has failed the test as some parts of the response haven't been documented. Specifically an instanceList array that contains maps with two keys: title and body. You can document those and the other two fields with something like this:
responseFields(
fieldWithPath('totalCount').description('Total count'),
fieldWithPath('type').description("Type of result"),
fieldWithPath('instanceList[].title').description('Foo'),
fieldWithPath('instanceList[].body').description('Bar')
)))
If you don't care about potentially missing fields, you can use relaxedResponseFields instead of responseFields:
relaxedResponseFields(
fieldWithPath('totalCount').description('Total count'),
fieldWithPath('type').description("Type of result")
))
This won't fail the test if some fields are not mentioned.