I have an Api Gateway GET method called /tasks/{tasktype}
It's pointed to a Lambda function with the X-Amz-Invocation-Type set to 'Event'
Then in my Lambda I have this
public void FunctionHandler(Object input, ILambdaContext context)
{
LambdaLogger.Log($"GOT: {input.ToString()}");
}
This all works fine, except input is null.
Is there any way I can pass through and access the value of {tasktype} from the Api Gateway?
Thanks
You need to pass them in using either a mapping template or check the box for "Use Lambda Proxy integration".
Mapping Template reference:
https://docs.aws.amazon.com/apigateway/latest/developerguide/api-gateway-mapping-template-reference.html
Proxy Integration reference:
https://docs.aws.amazon.com/apigateway/latest/developerguide/set-up-lambda-proxy-integrations.html
I have a rest service in spring which can return a string or a json. For this in my js code while sending the ajax request, i have specified datatype as "*". I wanted to know how can i handle this in spring service
All produces type are available in org.springframework.http.MediaType and for your requirement you can pass */*.
Constant for that is MediaType.ALL_VALUE in java code.
But if you know that your service always return JSON then I prefer to use MediaType.APPLICATION_JSON_UTF8_VALUE instead of MediaType.ALL_VALUE.
you can add attribute " produces" on your RequestMapping annotation:
#RequestMapping(value = "/yourPath", method = GET,
produces = { "application/json", "application/xml",....all what you want as type})
I have added Swagger to my Spring Boot 2 application:
This is my Swagger config:
#Configuration
#EnableSwagger2
public class SwaggerConfig {
#Bean
public Docket api() {
// #formatter:off
return new Docket(DocumentationType.SWAGGER_2)
.select()
.apis(RequestHandlerSelectors.any())
.paths(PathSelectors.any())
.build();
// #formatter:on
}
}
This is Maven dependency:
<!-- Swagger2 -->
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger2</artifactId>
<version>2.8.0</version>
</dependency>
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger-ui</artifactId>
<version>2.8.0</version>
</dependency>
When I try to invoke for example http://localhost:8080/api/actuator/auditevents it fails with the following error:
TypeError: Failed to execute 'fetch' on 'Window': Request with GET/HEAD method cannot have body.
What am I doing wrong and how to fix it ?
I ran into this issue. Here is how I resolved it:
I had a method like this:
[HttpGet]
public IEnumerable<MyObject> Get(MyObject dto)
{
...
}
and I was getting the error. I believe swagger UI is interpreting the Get parameters as FromBody, so it uses the curl -d flag. I added the [FromQuery] decorator and the problem was resolved:
[HttpGet]
public IEnumerable<MyObject> Get([FromQuery]MyObject dto)
{
...
}
FYI this also changes the UI experience for that method. instead of supplying json, you will have a form field for each property of the parameter object.
The error message actually says what the problem is. You post data with curl using the -d option while trying to use GET.
If you use the -d option curl will do POST.
If you use -X GET option curl will do GET.
The HTTP GET method is for requesting a representation of the specified resource. Requests using GET should only retrieve data and hence cannot have body.
More info on GET vs POST
I had same problem with my .net core 2.0 solution and GET method that takes element id as header key or search for it by parameters in body. That is not the best way to implement but it's kind of special case.
As mentioned in this discussion. The HTTP spec does not forbid using body on a GET, but swagger is not implementing it like this. Even if there are APIs that work fine with body in GET Requests.
What more, the swagger frontend adds this body object into request even if it is null/undefined/empty object. It is -d "body_content_here" parameter. So in my case when i only search by id and body is empty, it still sends empty object (-d "{}") and throws mentioned error.
Possible solutions:
Start using postman app for this request - It will work fine. Tested.
Consider moving more advanced GET request (like search with criteria) to the independent POST Method
Use swagger generated CURL request request without -d parameter
Don't pass method type in Get method.
let res = await fetch("http://localhost:8080/employee_async",{
method: "POST",
body:JSON.stringify(data),
mode:"cors",
headers: {"Content-type":"application/json;charset=utf-8"}})
This is used for post only, If we don't assign any method type node automatically considered as Get method
To avoid this error be sure to annotate parameters in your controller with #RequestParam, like
#GetMapping("/get")
public Response getData(#RequestParam String param)
Looking at swagger exception/error message , looks like you are calling Get method with a set of input body. As per documentation of GET method doesn't accept any body. You need to change the GET method to POST method. It should work.
Maybe the problem is with the mapping of the method, make sure to use
#RequestMapping(value = "/<your path>" , method = RequestMethod.POST)
and put the data as body with #RequestBody
I also got the same error on the Swagger UI. My problem was I have mistakenly marked the Api Method as GET and send data in the request body. Once I change the annotation #GET to #POST issue got resolved.
Because you used GET http method with body.
If you want to have Json body, etc you need to use POST http method,
For example in your controller class, top of your method:
#PostMapping(value = "/save")
public ResponseEntity<HttpStatus> savePerson(#RequestBody Person person)
{...}
Use GET without body.
Pass Paremeters with [FromQuery] in Methods InPut
I was having this issue when trying to use Swagger UI on a Ruby On Rails app. I fixed it by changing the information container on the curl command. This is a example line:
parameter name: :body, in: :body, schema: {'$ref' => '#/definitions/ActivitiesFilter'}, required: true
into
parameter name: :attribute_name1, in: :query, required: true
parameter name: :attribute_name2, in: :query, required: true
parameter name: :attribute_name3, in: :query, required: true
note that you have to add as many lines as attributes are defined on your schema inside swagger_helper
This errors happens with wrong argument type. Just change "[FromBody]" to "[FromQuery]".
I faced similar issue; now, it's resolved.
You cannot pass parameter to HTTPGET thru Body.
To pass parameter to HTTPGet, there are 2 ways either use [FromRoute] or [FromQuery].
If u use [FromRoute], then
[HttpGet("{param1}/{param2}")]
public Person Get([FromRoute]string param1, string param2)
{
}
For PersonController,
from client side your url should be:
http://localhost:000/api/person/value1/value2
If u want to use [FromQuery]
[HttpGet]
public Person Get([FromQuery]string param1, string param2)
{
}
from client side your url should be:
http://localhost:000/api/person?param1=value1¶m2=value2
Well, I am stuck in this scenario that I want to use Swagger API to validate response of my Lagom Service API.
Here is some sample code:
#Test
public void shouldPayloadFromFileConformToSchema() throws Exception {
// first test the plain json is valid with schema
SwaggerRequestResponseValidator validator = SwaggerRequestResponseValidator
.createFor("my-service-schema.yaml").build();
final Request validRequest = SimpleRequest.Builder.get("/myService/AL20170730/11111555556161/191919")
.withHeader("api-key", "TESTKEY")
.build();
Response validResponse = SimpleResponse.Builder.ok()
.withBody(ValidatorTestUtil.loadResponse("my_service_sample_response_2017_03_16")).build();
ValidationReport reportForText = validator.validate(validRequest, validResponse);
logger.info(
"shouldPayloadFromFileConformToSchema() ################# VALIDATION PAYLOAD REPORT ##################");
reportForText.getMessages().forEach((m) -> {
logger.info("{}", m);
});
assertFalse(reportForText.hasErrors());
logger.info(
"shouldPayloadFromFileConformToSchema() ################# VALIDATION PAYLOAD REPORT END ##################");
logger.info(validRequest.getHeaders().toString());
SwaggerModule swagger = new SwaggerModule();
}
When This code runs It seems that it goes into the service(as it prints some logs of the service.) but not invokes the method which will the database with the given values.
I need to do something here that it invokes the method of the service and validates the response on the basis of this swagger spec.
I saw this link but didn't get the solution How to validate API in tests with Swagger?
If you're looking to validate an actual interaction against your running service I'd recommend using the RestAssured module (https://bitbucket.org/atlassian/swagger-request-validator/src/master/swagger-request-validator-restassured/)
This will let you execute a request against your running service and then validate that the request/response interaction matches your swagger specification.
There's an example of its use in the examples module - https://bitbucket.org/atlassian/swagger-request-validator/src/master/swagger-request-validator-examples/src/test/java/com/atlassian/oai/validator/examples/restassured/SwaggerValidationFilterTestExample.java (note that the example there uses WireMock to stub out a real service, but you would replace that with your actual running service).
#JsonView
how can use like parameter from request:
#JsonView(header="range")
when response value,read request header range to exclude/include some field
JsonView provides "static" view mapping. so for your dynamic behaviour you can do like this:
// actual request handling is happened here
private ResponseEntity<SomeObject> processRequest();
// request handling with view limit in result
#JsonView(YourDefinedView.class)
#RequestMapping(value = "/request", headers={"range=include"})
public ResponseEntity<SomeObject> processWithView() {
return processRequest();
}
// request handling without view (no headers specified)
#RequestMapping(value = "/request")
public ResponseEntity<SomeObject> processWithoutView() {
return processRequest();
}
this will map your client to same request url, but depending on header it will provide view or not. Than you can create a set of methods, that will be using different #JsonView depending on headers information.
But with this you will limit only the data transfered to client, and the whole data load will happen on server. For example with database and JPA, if you would like not to fetch from database all that data you will end with javax.persistence.NamedEntityGraphs, which will change the general logic of your application - and will at the end of the day produce 2 different methods.
And if you would like to expose custom header with list of fields, to be serialized - custom DTO object, or Map<String, Object> (ugly-ugly-ugly) or custom HandlerMethodReturnValueHandler comes to your help.