That’s definitely the configuration that allows you to directly call lambda from cloudfront. I think the key bit was using a custom SSL certificate. It is just a free AWS certificate with my domain name in it.
I am going to add this in here that API Gateway actually does a helluva lot for you to justify its price. For one, its already solved the problem of calling Lambdas via Cloudfront for you. Other than that it allows for ease of integration with authorizers to protect your API’s behind credentials, throttling of requests to prevent your architecture from getting flooded, API key control to 3rd parties to allow you to control their usage limits, caching of queries, generation of swagger definitions and with that SDK’s for your clients and a lot more.
As a counter to APIGateway – it adds cost and slows every call down. If you are using Sig4 as your authorizer you don’t need it. If you are not using Sig4 you have to have it. Similar throttling can be achieved by setting lambda currency limits. This throttling is not DOS protection - AWS Shield addresses that.
One thing you missed, lambda can only return JSON. API Gateway can use transforms to change that JSON into other things. For example if a lambda returns HTML as a JSON result, API Gateway can strip the JSON and return an HTML page. If you are selling gateway access to a third party, APIGateway is definitely the way to go.
API caching is a mixed bag. For our situation the calls are rarely repeated (they are unique to the user) so there isn’t much to cache. Plus our lambda response is very fast so I am not sure that a cache response from API gateway would matter. We don’t generate content dynamically for non-logged in users. That content is generated once (when it changes) into S3 where it then gets picked up by cloudfront.
I also believe a majority of mobile apps call lambda directly. If you use the AWS SDK in the mobile app, then you are calling lambda directly. I stumbled into this initially because we wanted to make a web app that mimicked our phone app. The phone app used the AWS SDK so it called lambda directly. When I went to work on the web app I simply make it work like the phone app.
As far as I know the only thing you can return from a lambda is JSON. In my case I catch that JSON in the browser and then turn it back into whatever form I need it in.