As with every project, CORS does problems. This is a manual for future me on how to set it correctly.
Option 1 - the hard way
By the hard way, I mean specifying CORS manually in the openapi schema specs file.
I started normally, as one does, by googling (actually I use DuckDuckGO, but this is a little offtopic). I entered “enabling CORS on API gateway openapi” and a bunch of results came out. I created OPTIONS methods on all the endpoints that I wanted to enable CORS and tried to figure how to specify the responses by combining various information from around the internet.
As you can imagine, without any previous knowledge on CORS on api gateway and trying to parse various articles, I failed spectacularly.
Option 2 - the easy way
Create all your API resources without any OPTIONS methods. I also removed this code from my AWS::Serverless::Api
resource in template.yaml
as it seemed to do nothing at all:
Cors:
AllowMethods: "'*'"
AllowHeaders: "'*'"
AllowOrigin: "'*'"
AllowCredentials: false
When you are done with creating the resources, follow these steps:
Go to AWS API Gateway console, select your api and go to resources section.
Locate the resource that you want to enable CORS for. Click the resource itself, not the GET method.
Click Enable CORS and configure as desired. This option automatically creates a response for OPTIONS method in your API. - Repeat this step for every endpoint.
After configuring, do not forget to click Deploy API. This is the single most frequent reason that causes me confusion when working with API Gateway in the console, I just always forget to deploy the API.
Test if the CORS configuration works as intended.
Go to Stages in the left side menu.
Select the stage that you deployed your CORS configuration to.
Under stage actions choose Export.
- Configure as needed and export
Merging the api gateway changes to your api specs file
My workflow is as follows:
Commit your api specification to git
Replace the content of the file with the specification exported from API Gateway console.
Go to commit view in your favourite IDE
Revert all changes not related to CORS setting
Make sure not to overwrite any advanced functionality, as statements like Fn:GettAtt
or Fn::Sub
will be already evaluated in the exported file. For example this code
credentials:
Fn::GetAtt: [ ApiDynamoDBRole, Arn ]
Gets transformed to:
credentials: "arn:aws:iam::xxxxxxxxxxxx:role/matejpokorny-blog-ApiDynamoDBRole-yyyyyyyyyyyy"
The code may work even when you left these substitution out, but If you change the role in the future or do other changes, this may cause hard to find bugs.
If everything worked out, try to deploy your API and CORS should be working the same way as it was after configuring in the console.