How do I define and validate URL Query String Parameters for an AWS::Serverless::Api in a SAM template?
They don't seem to be mentioned in the documentation https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/sam-resource-api.html
Just to be clear this is what I am talking about
The URL Query String Parameters is defined in AWS::Serverless::Function rather than AWS::Serverless::Api using RequestParameters property.
All parameter names must start with method.request and must be limited to method.request.header, method.request.querystring, or method.request.path.
For example to define email, name in URL Query String Parameters and Authorization in HTTP Request Headers u can do the following:
Events:
ApiEvent:
Type: Api
Properties:
Path: /path
Method: get
RequestParameters:
- method.request.querystring.email:
Required: true
Caching: false
- method.request.querystring.name:
Required: true
Caching: false
- method.request.header.Authorization:
Required: true
Caching: true
I hope this helps.
I think that your response is in another resource, AWS::ApiGateway::Method.
Check the documentation (search for Request Parameters):
The request parameters that API Gateway accepts. Specify request parameters as key-value pairs (string-to-Boolean mapping), with a source as the key and a Boolean as the value. The Boolean specifies whether a parameter is required. A source must match the format method.request.location.name, where the location is querystring, path, or header, and name is a valid, unique parameter name.
https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-apigateway-method.html#cfn-apigateway-method-requestparameters
Related
I have two http endpoints setup:
GET /users/{userId}
GET /users/{userId}/notes/{noteId}
The GET User returns a payload which includes a list of multiple noteIds, which can be used to make multiple requests to the GET Note endpoint.
I am trying to configure Appsync to be able to fetch all of this data in a single query, but I can't get the list to populate with objects.
Schema:
type Query {
getUser(userId: String!): User
getNote(userId: String!, noteId: String!): Note
}
type User {
userId: ID!
firstName: String!
lastName: String!
notes: [Note]
}
type Note {
noteId: ID!
noteText: String!
createdDatetime: Int!
}
I have a data source setup for each of the endpoints and I have a resolver for getUser and for getNote - I also have a resolver for User.notes which is the same as getNote. These resolvers have this response mapping:
#if($ctx.error)
$util.error($ctx.error.message, $ctx.error.type)
#end
#if($ctx.result.statusCode == 200)
$ctx.result.body
#else
$utils.appendError($ctx.result.body, "$ctx.result.statusCode")
#end
My resolver for the GET Note (including User.note field resolver) endpoint looks like this:
{
"version": "2018-05-29",
"method": "GET",
"resourcePath": $util.toJson("/prod/users/$ctx.args.userId/notes/$ctx.args.noteId"),
"params":{
"headers":{
"Content-Type": "application/json",
}
}
}
I can see from the logs, that Appsync attempts to run the GET Note resolver, but that the resource path doesn't seem to get populated with any ids? (I can see this in the custom Authorizer on the endpoint, which logs out the method ARN which still includes the $ctx.args...
It feels like this is a common use case, but I can't find a solution, or examples anywhere. Is my approach correct, or do I need a different solution?
I think the first problem is with your User.notes resolver and how you are accessing userId and noteId. When you have field resolvers, you should use ctx.source to access the the parent field [Ref.]. For example, you should use ctx.source.userId in your User.notes field resolver.
Secondly, as you are going to fetch individual notes from your getNote HTTP endpoint, AppSync supports this type of behavior when proxied through AWS Lambda using BatchInvoke. Please see "Advanced Use Case: Batching" on this link to get better idea. Also, I think this SO post is relevant to your use case.
One other possibility is to have another HTTP endpoint to get all the user's notes at once but I am not sure if this is possible in your case.
I work with API Manager version 3.0.0.
In Publisher page in Resources,I need add two or more parameters when the type is BODY with the method HTTP is POST, similar to but only permits one when parameter is Body.
Is possible to add more than one parameter BODY? and how?
Edit:
Is possible have two parameters in BODY, whit this form in API Publisher-> API Definition -> Edit, edit the service that you need similar to:
/v1/nipCliente:
post:
requestBody:
content:
application/x-www-form-urlencoded:
schema:
type: "object"
properties:
id_usuario:
type: "string"
password:
type: "string"
nip:
type: "string"
required: false
responses:
200:
description: "ok"
security:
-
default: []
x-auth-type: "None"
x-throttling-tier: "Unlimited"
In the same page looks that:
In API Developer->Try Out, looks similar to:
Multiple body parameters in POST, PUT requests are NOT allowed by design because there can be only one payload for the request. [1]
If the request body contains multiple parameters, you can send it as a single json object.
The backend service method should be modified to accept the specific object model.
Ex: Say I want to send the following as the body.
{
"name" : "Joe",
"age" : 23,
"grade" : 9
}
The backend service method which expects Student object.
#POST
public Response studentPost(Student student) {
}
Student Object
public class Student{
String name;
int age;
int grade;
... getters/ setters ...
}
Or, you can use different parameters. i.e, query params + body + header params.
[1] https://github.com/OAI/OpenAPI-Specification/blob/master/versions/2.0.md#parameter-object
My current configuration limits the number of properties and size of the request body for every endpoint. Should I return an error if request body has more information than needed?
Let's say that /authenticate endpoint requires JSON body shown below:
{
"login": "string";
"password": "string";
}
and the user sends a request
{
"login": "mylogin",
"password": "mypassword",
"foo": "bar"
}
Should REST API return an error in this case?
There are two options here:
1. Ignoring fields that don't affect request processing and cannot change it.
By default, most of JSON/XML parsers, filling an entity, skip fields that haven't been reflected in the model.
2. Strict field matching and returning the HTTP 422 UNPROCESSABLE ENTITY or 400 BAD REQUEST code.
You could have a list of all allowed fields for each endpoint to compare an incoming request with.
It depends on your API design and the style you want users to follow.
By default, the request is not validated for additional fields. For json schema there's a parameter 'additionalProperties', whose value can be set to false.
Refer this link Understanding JSON schema validation. Relevant portion copied below.
The additionalProperties keyword is used to control the handling of extra stuff, that is, properties whose names are not listed in the properties keyword. By default any additional properties are allowed.
The additionalProperties keyword may be either a boolean or an object. If additionalProperties is a boolean and set to false, no additional properties will be allowed.
My web service API will check whether a certain cookie is included in the requests, but I couldn't figure out how to include a cookie to my swagger doc api calls.
I've tried two approaches:
Adding cookie as a editable field like this in my .yaml file.
paths:
/myApi/create:
parameters:
- name: Cookie
in: header
description: cookie
required: true
type: string
In the html file of swagger ui, add
window.authorizations.add(
"Cookie",
new ApiKeyAuthorization("Cookie", 'Name=Val', 'header')
)
But in both of the approach my api doesn't get the cookie, I was wondering how I can do this? Thanks!
OpenAPI/Swagger spec 2.0 does not support cookie authentication. For the next version (3.0), the discussion to support it can be found in the following:
https://github.com/OAI/OpenAPI-Specification/issues/15
UPDATE: OpenAPI spec 3.0 will support cookie: https://github.com/OAI/OpenAPI-Specification/blob/OpenAPI.next/versions/3.0.md#parameter-locations
Maybe it is too late, but you should check the following example:
swagger: '2.0'
info:
version: '1'
title: With Cookie Authentication
description: With Cookie Authentication
securityDefinitions:
myCookie:
type: apiKey
name: Cookie
in: header
paths:
/say-hi:
get:
summary: Say Hello
description: Say Hello
responses:
200:
description: OK
security:
- myCookie: []
We are using swagger for api documentation.
I'm facing an issue on tryit out. Basically the rest endpoints which we indent to call from swagger requires
Cookie(ex: cookie : token=xxxxx;) and User-Agent(User-Agent:custom values;) parameters.
But when I try to set this parameter
Cookie is not send as part of the request.
User-Agent is being overridden by browser values. I tried on firefox and chrome both.
I did tried search online but didn't find suitable answer solve my issue, There were suggestion to set
useJQuery: true and withCredentials: true to set the cookies, but non worked fine.
Any suggestion on this?
As presented on their website:
In OpenAPI 3.0 terms, cookie authentication is an API key that is sent
in: cookie. For example, authentication via a cookie named JSESSIONID
is defined as follows:
openapi: 3.0.0
...
# 1) Define the cookie name
components:
securitySchemes:
cookieAuth: # arbitrary name for the security scheme; will be used in the "security" key later
type: apiKey
in: cookie
name: JSESSIONID # cookie name
And then at the endpoint level:
paths:
/users:
get:
security:
- cookieAuth: [] # note the arbitrary name defined earlier
description: Returns a list of users.
responses:
'200':
description: OK
For swagger: "2.0" you can define cookie authentication like this:
securityDefinitions:
cookieAuth:
type: apiKey
name:
Cookie # this is actually the Cookie header which will be sent by curl -H
in: cookie
Referencing it at the endpoint is done the same way as for OpenAPI 3.