A small tool for debugging path issues between CloudFront, API Gateway, and ECS

I recently ran into one of those AWS issues that looks obvious in hindsight, but is surprisingly annoying while you are debugging it.

A request was going through CloudFront and API Gateway. The API Gateway route matched. Everything looked fine there. But the backend running in ECS still returned 404.

In the end, the issue was not whether API Gateway matched the route. It was about which path was actually forwarded to the backend.

In my case, the public URL looked something like this:

API Gateway had a custom domain mapping for /api, and the actual route in API Gateway was:

At first glance that looked correct. API Gateway matched /endpoint, and my backend also expected:

But with a private integration, the path sent to the backend is not always the same as the path API Gateway uses for route matching. In practice, the backend could receive something like:

And since the backend only knew about /endpoint, it returned 404.

To make this easier to reason about, I built a small debugging tool:

CloudFront API Gateway Integration Debugger

The tool lets you enter a browser URL and then change the relevant parts of the request chain step by step:

  • CloudFront behavior path pattern
  • CloudFront origin path
  • optional CloudFront Function URI rewrite
  • API Gateway custom-domain mapping
  • API Gateway route matching
  • private integration path handling
  • overwrite:path = $request.path

The goal is not to perfectly simulate every internal AWS detail. The goal is to make the path flow visible: what CloudFront receives, what API Gateway matches, and what the backend actually gets.

It also lets you compare different setups. For example, I previously had a CloudFront Function that removed /api before forwarding the request:

That worked because the backend received /endpoint.

Later, when the /api handling moved to API Gateway custom-domain mapping, the route still matched, but the backend did not necessarily receive the same path anymore. That is the kind of subtle difference that is easy to miss.

The main lesson for me was that API Gateway route match and backend integration path are related, but not always identical.

Hopefully the tool can save someone else a bit of time the next time CloudFront and API Gateway look correct, but ECS still responds with 404.

Truncate (Trunk8) for Angular – Simple Directive

Since no one has done it already, I did a simple Angular directive for the awesome Trunk8 by Rick Viscomi. Note: It’s not thoroughly tested, and requires jQuery. I added a zero-timeout to allow the template to render before trunk8 is applied.

Usage:

Settings (Default value):

Source code:

How to handle hover on touch devices in simple way [JavaScript + CSS]

We have all been there! You make a responsive web site, add some hover effects as usual.
You try out the site on your touch device, and suddenly strange things start to happens to all kinds of elements when you scroll.
That’s because as soon as you touch the elements, but don’t click them, the browser triggers the hover state.

A lot of really good developers out there want us to treat the desktop users and the touch users the same. But they don’t have the same possibilities, so why?. Just because touch users can’t use the hover state properly, doesn’t mean we shouldn’t aid the desktop users. It helps a lot when navigation around a page!

However, when you use hover effects, beware that your touch users won’t get any help from it. So don’t, for example, rely on tool tips and let the touch users hang dry.

So to allow the desktop users and touch devices to coexist we simply remove the hover effects for touch devices.
It would be super simple if you could use Modernizr to test whether it’s a touch device or not.

But you can’t This method cannot be trusted. There are just to many false positives stacking up.

For example, with the update of Firefox to version 36, my desktop at work report that it’s a touch device. So is Chrome on one of the laptops the testers use in my project.

The only way you can reliably detect a touch device, that I know of, is to listen for an actual touch.
To do this can use a the JavaScript below.

First do I quick and dirty check in case you need to condition something during page load, and the we add a touch test which will only be fire in case a user actually has a touch device.

Note: The second test will not fire until the user actually touch the screen.

Please also note that until we actually know if it’s a real test device or not, the divice will be both touch device and not. Like Schrödinger’s cat or a quantum state.

So now we have the JavaScript in place. Lets move on to the CSS.

You can use the following states, although you should try to avoid using anything else then the ‘no-touch-device’ class, which is the default class for all devices before the test is done.

This is what a real example would like in your stylesheet

Try a live example here:

See the Pen WbKbaN by Jon WAllsten (@JonWallsten) on CodePen.

How to avoid scroll leakage when scrolling a fixed menu on touch devices

When I was working as a frontend developer for a retailer, developing a web shop, I stumbled upon a tricky problem.
My customer was pretty picky, and didn’t want any edge case flaws.

We had a fixed (or sticky of you supported that) navigation that was always attached from top to bottom.
The nav did only cover about 2/3 of the screen’s width though, so when the user reached the end of the content,
you could see how the background started scrolling instead. The scrolling was leaking upwards to the body.

Note: This has been fixed in iOS 8 but is still a valid defect in iOS 7 and below, as well as Android.

To fix this you need to listen to the touchstart and touchmove events and check where you are in the content and which direction you are scrolling.
When you have reached the bottom of the container and the direction you are scrolling is downwards we simple use preventDefault() to stop the scroll event,
to avoid it leaking to the body content.

The wrapper covers the whole screen so when user scrolls outside of the menu, it will still scroll the menu.
It’s using a semi-transparent color to appear modular.

The content covers the width of the menu.

I also need to mention that this solution is not perfect on Android devices.
If you scroll almost all the way to the bottom, and then scrolling past the bottom without lifting you finger, the scroll will leak with the following error message in the console:

Ignored attempt to cancel a touchmove event with cancelable=false, for example because scrolling is in progress and cannot be interrupted.

A way around this, is to implement a custom scroll like iScroll, this is what we ended up doing, although not optimal, of course.

Here’s the JavaScript fixing the problem, I have explained the code with comments inside the script itself.

Try it out on your device:
https://jonwallsten.com/codepen-examples/example1/

See the Pen RNMrmP by Jon WAllsten (@JonWallsten) on CodePen.