I have been trying and searched online, but was not able to find a response. Is it possible to achieve the following using Serverless Framework:
I want to use the get.handler that has the code to the following definition for both getting one item and getting all the items. So:
if I hit api.example.com/items/ I retrieve all the items
if I hit api.example.com/items/1234 I retrieve item with id = 1234
- get_items:
handler: project/items/get.handler
events:
- http:
path: items/{itemId}
method: get
So far in the get.handler I check event.pathParameters? event.pathParameters.itemId : null if the specific item exists and call some getItem(itemdId) function and if it does not exits I call a getAll() function.
If I pass the item id in the path it works, but when I make a request for api.example.com/items/ I get the following error:
not a valid key=value pair (missing equal-sign) in Authorization header. This means something is wrong in my path and I have to pass the item id to the path parameters.
My question is: Is there a way I can use multiple paths in the - http: area, or what would be a recommended way to solve this issue (just create two separate handlers) ?
There are two ways to easily accomplish what you're looking for.
Firstly, a lambda function can be triggered by multiple events. You can add another http event to the array of handlers like so:
get_items:
handler: project/items/get.handler
events:
- http:
path: items/{itemId}
method: get
- http:
path: items/
method: get
Alternatively, you could use the {proxy+} argument. You can read more about the various proxy methods here
Related
In Postman, I can create a set of common tests that run after every endpoint in the collection/folder Tests tab, like so:
pm.test("status code is 200", function () {
pm.response.to.have.status(200);
});
But how should I do this for my schema validation on the response object? Each endpoint has a different expected schema. So I have something like this on each individual endpoint:
const schema = { type: 'array', items: ... }
pm.test('response has correct schema', function () {
const {data} = pm.response.json();
pm.expect(tv4.validate(data, schema)).to.be.true;
});
I can't extract this up to the collection level because each schema is different.
Now I find that I want to tweak that test a little bit, but I'll have to copy-and-paste it into 50 endpoints.
What's the recommended pattern here for sharing a test across endpoints?
I had the same issue some years ago, and I found two ways to solve this:
Create a folder for each structure object
You can group all your test cases that share the same structure into a new folder and create a test case for this group. The issue with this is that you will be repeating the requests in other folders. (For this solution, you will need to put your "tests cases" into the folder level)
Create a validation using regular expressions (recommended)
Specify in the name of each request a set of rules (these rules will indicate what kind of structure or call they might have). Then you create a validation in the first parent folder for each type of variation (using regex). (You will need to create documentation and some if statements in your parent folder)
E.g.: [POST] CRLTHM Create a group of homes
Where each initial is meaning to:
CR: Response must be 201
LT: The response must be a list of items
HM: The type of the response must be a home object
And the regex conditional must be something like this (this is an example, please try to make your regex accurate):
if(/CRLTHM\s/.test(pm.info.requestName))
(In this image, NA is referring just to Not Authenticated)
The project uses a swagger.
There is the following code.
#swagger_auto_schema(
manual_parameters=[
Parameter('download', IN_QUERY,
'Set `Content-Disposition=attachment` to make browser to download file'
'instead of showing it.',
type='bool'),
Parameter('share_id', IN_PATH, type='uuid')
],
security=[],
responses={'400': 'Validation Error (e.g. base64 is wrong)',
'200': VideoSerializer}
)
Please explain what each argument is responsible for.
I read the documentation, but understood little ...
Particularly interested in '200': VideoSerializer
responses
The responses argument is a dictionary of possible responses that this endpoint can return.
400 and 200 are HTTP response codes, Bad Request and OK respectively.
In this case, this means that this endpoint can generate two types of responses:
Bad request which will also return (as described) a Validation Error which means that something in the request was incorrect, which means it could not be handled correctly.
OK, which means the request is correct, and everything was handled correctly. VideoSerializer means that a response will be given with accordance to the structure of the VideoSerializer, which defines a collection of fields.
The other two arguments:
manual_parameters
This a custom list of parameters that can be added to the request to customize the response.
In this case, two parameters are defined:
download : A query parameter of type bool. Query parameters are passed like this : `example.com?query_parameter=true
share_id, a path parameter of type 'uuid'. Path parameters are passed like this : example.com/path_parameter
security
A list of security schemes that the request must adhere to. Used for instance for Basic authentication.
I've only seen examples with single values in SAM templates:
Environment:
Variables:
TABLE_NAME: my-table
I want to do something like this but doesn't seem to work:
Environment:
Variables:
myVar:
- prop1: aaa
prop2: sdfsdfsd
prop3: ssss
- prop1: bbb
prop2: wwwwww
prop3: aaaaa
I want to have an environment variable that is like a list of objects. I could store a delimited string and parse it myself but I'd prefer to have it be like an object/map/list like if I'm ready a YAML file.
The closest you can do is to json encode the value for your environmental variable
and decode it using the runtime language:
Environment:
Variables:
USER: '{"name": "john", "surname": "galt"}'
If you want to prevent decoding json on each request, move your decoding logic outside the handler, in this case code won't be re-executed while lambda is hot.
Any declarations in your Lambda function code (outside the handler code, see Programming Model) remains initialized, providing additional optimization when the function is invoked again. For example, if your Lambda function establishes a database connection, instead of reestablishing the connection, the original connection is used in subsequent invocations. We suggest adding logic in your code to check if a connection exists before creating one.
Read about lambda execution model
I personally would create a json file, store it in s3 bucket and use an environment variable to specify s3 url to that file. Additionally, use the same technique I mentioned above or use even more complicated caching mechanism depending on the situation when retrieving the config file
I am using ember-rest in my application for persistence layer, and it has been working great. One of the resources that I am working with, requires some optional resource parameters. Looking at the ember-rest source code, I couldn’t find anything related to setting request parameters, but it is possible that I overlooked something.
My question is, does ember-rest provide a way to specify request parameters to be appended to the URL? If not, some advice about how I should add this functionality to ember-rest would be very appreciated.
For example, I am working with a resource called blocki which comes with the following REST api:
POST /api/apps/:app_id/blockies?parent=:parent_id
- default :parent_id=:app_id
- TODO: error if the blocki cannot be placed in :parent_id
PUT /api/blockies/:id
PUT /api/blockies/:id?parent=:parent_id
- update the blocki and reparent it
DELETE /api/blockies/:id
As you can see when I do a put request to update this resource I can optionally pass a parent_id if I want to update that. I want to achieve this using ember-rest.
You can completely customize the url for a resource or resource controller by overriding the _resourceUrl() method. For instance:
_resourceUrl: function() {
return this._super() + '?parent=' + this.get('parent_id');
}
I have the following Url which returns me the list of resources:
http://example.com/resources/
I also implemented a method which returns a specific resource (in this case, the resource 142).
http://example.com/resources/142
I would like to add a method which is outside the typical HTTP method: List, Create, Retrieve, Replace, Update. What is the pattern to follow? In my specific case, I need to check the availability of resource. How would the Url look like (http://example.com/resources/checkavailability/142)?
I though about simply using the GET method and retrieve that information as part of the object returned. However, some of my colleagues argue that this would not be efficient (the data to transfer would be much bigger than just returning true/false).
Thanks for the help!
There is no need for a resource to check the availability of another resource, and there is no need for a GET request, a HEAD request should be enough, this is the same as a GET request but without transferring the body. You can then look at the return codes, and via those determine if the resource is available. This is assuming you have properly implemented return codes.
Restful over HTTP gives you uniform interface, you often don't need to encode the actions inside your URL
Regarding your mentioned /checkavailability using GET returning payload inefficiency is a valid reason, so use HEAD (it only gives you back the response headers).
request:
HEAD /resources/123
response status:
404 Not Found: equals to /checkavailability == false
200 OK: equals to /checkavailability == true
Other suggestions uniform interface replacements:
/resources/list : GET /resources
/resources/replace/123: PUT /resources/123
/resources/update/123: PUT /resources/123
/resources/create: POST /resources