-
Notifications
You must be signed in to change notification settings - Fork 1
Description
A problem I'm having at the moment is reusing a base style, osm-liberty for example, while adding my own symbol layers on top. This is currently hard because I'd have to regenerate the osm-liberty stylesheet to include my images. If osm-liberty updates it's spritesheet I need to be aware of that and regenerate the spritesheet again. This is a massive pain and make reusing styles hard.
I believe this library can improve this experience by remixing stylesheets. I think we can do this by adding a type to our images definition. So where as currently we can pull in only images
[
{"id": "red", "url": "http://example.com/images/red.jpg", "width": 20, "height": 20},
{"id": "green", "url": "http://example.com/images/green.svg", "width": 32, "height": 32},
{"id": "blue", "url": "http://example.com/images/blue.png", "width": 20, "height": 20}
]We'd also be able to pull in any sprite. An example might be
[
{
"type": "spritesheet"
"url": "https://maputnik.github.io/osm-liberty/sprites/osm-liberty"
},
{"id": "red", "url": "http://example.com/images/red.jpg", "width": 20, "height": 20},
{"id": "green", "url": "http://example.com/images/green.svg", "width": 32, "height": 32},
{"id": "blue", "url": "http://example.com/images/blue.png", "width": 20, "height": 20}
]This would pull in all the images from https://maputnik.github.io/osm-liberty/sprites/osm-liberty repackaging them along with the other images into a new spritesheet.
The caching etag would also now be generated from both the definition (shown above) and the JSON source of the https://maputnik.github.io/osm-liberty/sprites/osm-liberty endpoint. This means that if the sprites change at the external endpoint we'll send a 304 not modified.
I think we can do this with a combined hash of all the resources, concatinating the hashes with a | char (or something better)
So we resolve definition like so
[
{
"type": "spritesheet"
"url": "https://maputnik.github.io/osm-liberty/sprites/osm-liberty"
},
{"id": "red", "url": "http://example.com/images/red.jpg", "width": 20, "height": 20},
{"id": "green", "url": "http://example.com/images/green.svg", "width": 32, "height": 32},
{"id": "blue", "url": "http://example.com/images/blue.png", "width": 20, "height": 20}
]Then we'd remove any spritesheet's from the definition so we'd now have 2 sets of resources.
[
{"id": "red", "url": "http://example.com/images/red.jpg", "width": 20, "height": 20},
{"id": "green", "url": "http://example.com/images/green.svg", "width": 32, "height": 32},
{"id": "blue", "url": "http://example.com/images/blue.png", "width": 20, "height": 20}
]{
"type": "spritesheet"
"url": "https://maputnik.github.io/osm-liberty/sprites/osm-liberty"
}Now the HTTP request has passed a If-None-Match to match against our etag we'll split by our | and pass the If-None-Match to each resource on request. An example the HTTP request to our server comes with the following If-None-Match header
W/"5ed0f108-6789|6ed0f231-9271"
We make requests to each resource passing the hash via the If-None-Match which will in turn return a 304 if matched.
Although you could pull from multiple external resources that is probably unlikely. However if you do if one request 304's and the other doesn't. Then you'd need to re-request the data from the endpoint that returned 304 to get the body of the content.
The idea of all of this is that we're passing on the least work as we can to our down stream servers, letting the browser or CDN cache return the cached response.