koopjs / koop

Transform, query, and download geospatial data on the web.
http://koopjs.github.io
Other
651 stars 125 forks source link

Ability to augment featureServer capabilities ouput #588

Closed efbenson closed 9 months ago

efbenson commented 1 year ago

I am looking into some preliminary ways to add apply edits to a provider, but there is no easy way to augment the supported capabilities in the featureServer info endpoint. It would be nice if there was a way to enrich/change that as needed. To that point with implementing the related layers in our provider I have some recommendations on simplfiing the workflow for implementing custom providers. Right now all that is handed in the getData function with different data returned based on the use case. Splitting up the functions bases on purpose would also help with adding typing.

class MyProvider extends KoopProvider {

    async queryFeatureLayer(host, layer, id, query, req) {
        // Query the layer
        // return full dataset with metadata
    }

    async getFeatureServerInfo(host, layer, req) {
        // Also maybe provide a way to give some fields to override on the generated server info
        const serverInfo = this.generateBaseFeatureServerInfo({layers, tables, relationships});
        // make changes for custom capabilities

        return serverInfo
    }

    async queryRelatedFeatureLayer(host, layer, id, query, req) {
        // Probably could come up with some cleaner function params
        // returns full dataset with metadata
    }

    async createKey(req) {
        return myKey;
    }
}
rgwozdz commented 1 year ago

@efbenson - I see your need for some additional methods. One issue though is that these methods are coupled to FeatureServer output, which is just one of many possible Koop output-plugins. Other output plugins aren't concerned with generating server info, layer info, or relatedFeatureLayerInfo. So if they can be generalized, that's better. This means generalizing the names as well as the parameters; host and id might not exist for some providers (and we plan to deprecated host); layer, id, and query won't be defined for routes that don't arrive via the FeatureServer output-plugin, so you're better off just passing in the request object.

There is a one-one relationship between supported provider methods and supported output-plugin methods. If you look at the internals, you will see that invocation of one of the output methods ends up calling one of the provider methods:

output method provider method
pull getData
pullStream getStream
pullLayer getLayer
pullCatalog getCatalog

the getLayer method (there but not documented) may already be something you can use instead of queryFeatureLayer. However the key thing that needs to happen is that OutputGeoservices and FeatureServer would need to be reworked to:

  1. Use pullLayer and other methods for specific FeatureServer routes. pullLayer would try to call the provider's getLayer method if it was available. To preserve functionality with providers that don't define a getLayer we would need to fall back to getData
  2. Decide on the response format for getLayer and then adapt FeatureServer to use it instead of the GeoJSON returned by getData.

These would be pretty major changes to FeatureServer. I think they would be good, but definitely a major undertaking.

efbenson commented 1 year ago

@rgwozdz yep that makes total sense, I forgot there are uses for koop other than feature server 😄 . I am routing all those methods inside my getData, but I thoughtit would be helpful to call them out. If I make any progress with applyEdits ill let you know.

rgwozdz commented 9 months ago

As far as augmenting FeatureServer capabilities, there is a pathway now. See my comment on https://github.com/koopjs/koop/issues/599 for an example.

Going to close this issue, since augmentation is possible now. Granted, not all properties are overridable out of the box, so you would need to PR additions. Might be nice to generalize it so that wasn't necessary, but having validation for override value...is valuable.