StationA / tilenol

Scalable, multi-backend geo vector tile server
MIT License
22 stars 6 forks source link

External configuration with layer compositing #13

Closed jerluc closed 4 years ago

jerluc commented 4 years ago

Overview

This changeset introduces multiple changes relating to #11, primarily including the following major changes:

External configuration file

Most of the tile server configuration options have been migrated into an external YAML configuration file (defaults to tilenol.yml, but can be specified using -f/--config-file). The format is net-new, so I've added an example config to the README.md and under the examples/ directory as well. The reason this configuration has been externalized is to primarily to support:

  1. Saner multi-valued options: tilenol pre-v1.0.0 uses key=value flags for multiple values, but this is both error-prone and makes long lists of values awkward to write out on the command line. Using a YAML file, we get first-class support for arrays and mappings which have a specific syntax that is arguably easier to understand, manipulate, and iterate on.
  2. Saner nested options: tilenol pre-v1.0.0 used multiple separate flags that can actually be interdependent, e.g. --cache-ttl is not really useful if there is no --cache-server-address set. Using mappings and optional keys in a YAML configuration file makes things saner for the user to configure these optional, interdependent options (some of which may actually be conditionally required as well).
  3. Future extension: using an external YAML configuration with a fairly straightforward structure provides some of the plumbing needed for supporting future extension to tilenol

New code interfaces

In this changeset, there are a few new code interfaces that have been introduced in order to provide paths to future extensions to tilenol:

  1. Cache defines a generic interface to any number of backend cache implementations. Here, only RedisCache is supported, but future implementations might include things like InMemoryCache, FileCache, etc.
  2. Source defines a generic interface to multiple kinds of backend data sources for feature data. Here, only ElasticsearchSource is supported, but future implementations might include things like FileSource, ProxySource, PostGISSource, etc.

In addition to providing these notable extension points, these interfaces better define parts of the code that used to be cluttered with leakier abstractions.

Layer compositing

Tilenol pre-v1.0.0's primary endpoint took the form of: /{layer}/{z}/{x}/{y}.mvt. This implied that if you actually had multiple layers/indices behind tilenol, you'd need to configure a different Mapbox JS source for each layer/index. This also meant that you'd have an HTTP request made to tilenol fper tile for each layer.

This changeset introduces server-side layer compositing, whereby the tile endpoint is now: /{layer(s)}/{z}/{x}/{y}.mvt. This is allows Mapbox JS source configuration to specify one or more layers at a time (using comma-separated list of layer names, or the special _all value to use all configured layers). Under this scheme, tilenol queries the backend data sources configured for each layer requested in parallel and then composites the resulting GeoJSON FeatureCollection's into a single HTTP response. The result is fewer frontend HTTP requests, and in some cases, better compression and performance, especially in the cases of "unbalanced" layers (e.g. one layer with a ton of data and a bunch of other layers with only a small amount of data). Also, by using this endpoint scheme, we preserve backward compatibility, since this still allows one to continue using the one-layer-per-mapbox-source approach, if they so choose.

Note for the reviewers

Because this repo contains vendorized dependencies, I'd suggest ignoring any deltas for files under the vendor directory. If you do want to know more about what dependencies changed, you can refer to Gopkg.toml or Gopkg.lock to see what dependencies were added/removed/updated.