Context
The ESRIJSON driver currently requires users to manually construct /query URLs to read features from ArcGIS FeatureServer endpoints. For example:
# This works — but users have to know the query API
ogrinfo "https://example.com/.../FeatureServer/0/query?where=1%3D1&outFields=*&f=json"
# This does NOT work — returns no features (metadata JSON, not recognized)
ogrinfo "https://example.com/.../FeatureServer/0"
# This also does NOT work — multi-layer not supported
ogrinfo "https://example.com/.../FeatureServer"
This is a usability gap. ArcGIS FeatureServer is one of the most widely deployed vector data services, and users reasonably expect GDAL to handle these URLs directly — the same way WFS or OAPIF URLs work.
Related: #4613 (multi-layer support, reopened by @rouault as "a reasonable enhancement"), #12081 (pagination retry).
Current state
The ESRIJSON driver does have solid support for reading ESRI JSON responses, including:
- Field type mapping (
esriFieldType* → OGR types)
- ESRI geometry parsing
- Automatic pagination via
exceededTransferLimit / resultOffset
- GET/POST switching for long URLs
But the driver only activates for URLs containing f=json, f=pjson, or resultRecordCount= (see IsLikelyESRIJSONURL() in ogrgeojsonutils.cpp). A bare FeatureServer URL doesn't match any of these, so it's never claimed by the driver.
Proposal
I'd like to incrementally improve FeatureServer support. Before writing code, I want to check whether this approach makes sense to the maintainers.
Step 1 — Single-layer URL rewriting (small, extends ESRIJSON driver)
When opening a URL matching .../FeatureServer/<layer_id>:
- Detect it in
IsLikelyESRIJSONURL() / ESRIJSONDriverGetSourceType()
- In
OGRESRIJSONDriverOpen(), rewrite the URL to .../FeatureServer/<layer_id>/query?where=1%3D1&outFields=*&f=json
- Preserve any existing query parameters (e.g.
?token=...)
- The existing ESRI JSON parsing and pagination then handles the rest
This is ~50 lines of C++ in the existing driver, no new files.
Step 2 — Multi-layer discovery (medium, addresses #4613)
When opening .../FeatureServer (no layer ID):
- Fetch the service metadata JSON (
?f=json)
- Parse the
layers array to enumerate available layers
- Expose each as a separate OGR layer, with reads routed through
/query
This follows the same pattern as OAPIF (/collections → per-collection /items) and WFS (GetCapabilities → per-type GetFeature).
Step 3+ — Filters, auth, robustness (future)
Questions for maintainers
-
Should this live in the ESRIJSON driver or become a new driver? Step 1 naturally extends ESRIJSON. Step 2 starts to look more like a service driver (similar to WFS/OAPIF/Carto). Is there a point where it should become ogr/ogrsf_frmts/arcgis/?
-
Does Step 2 require an RFC? It adds multi-layer behavior to what's currently a single-layer driver. The code change is moderate (following existing patterns from OAPIF/WFS), but the architectural shift might warrant an RFC.
-
Any concerns with Step 1 as a starting PR? It's minimal and non-breaking — URLs that already have /query are not affected.
I'm happy to start with Step 1 as a PR if the approach looks right, or adjust based on feedback.
Context
The ESRIJSON driver currently requires users to manually construct
/queryURLs to read features from ArcGIS FeatureServer endpoints. For example:This is a usability gap. ArcGIS FeatureServer is one of the most widely deployed vector data services, and users reasonably expect GDAL to handle these URLs directly — the same way WFS or OAPIF URLs work.
Related: #4613 (multi-layer support, reopened by @rouault as "a reasonable enhancement"), #12081 (pagination retry).
Current state
The ESRIJSON driver does have solid support for reading ESRI JSON responses, including:
esriFieldType*→ OGR types)exceededTransferLimit/resultOffsetBut the driver only activates for URLs containing
f=json,f=pjson, orresultRecordCount=(seeIsLikelyESRIJSONURL()inogrgeojsonutils.cpp). A bare FeatureServer URL doesn't match any of these, so it's never claimed by the driver.Proposal
I'd like to incrementally improve FeatureServer support. Before writing code, I want to check whether this approach makes sense to the maintainers.
Step 1 — Single-layer URL rewriting (small, extends ESRIJSON driver)
When opening a URL matching
.../FeatureServer/<layer_id>:IsLikelyESRIJSONURL()/ESRIJSONDriverGetSourceType()OGRESRIJSONDriverOpen(), rewrite the URL to.../FeatureServer/<layer_id>/query?where=1%3D1&outFields=*&f=json?token=...)This is ~50 lines of C++ in the existing driver, no new files.
Step 2 — Multi-layer discovery (medium, addresses #4613)
When opening
.../FeatureServer(no layer ID):?f=json)layersarray to enumerate available layers/queryThis follows the same pattern as OAPIF (
/collections→ per-collection/items) and WFS (GetCapabilities→ per-typeGetFeature).Step 3+ — Filters, auth, robustness (future)
Questions for maintainers
Should this live in the ESRIJSON driver or become a new driver? Step 1 naturally extends ESRIJSON. Step 2 starts to look more like a service driver (similar to WFS/OAPIF/Carto). Is there a point where it should become
ogr/ogrsf_frmts/arcgis/?Does Step 2 require an RFC? It adds multi-layer behavior to what's currently a single-layer driver. The code change is moderate (following existing patterns from OAPIF/WFS), but the architectural shift might warrant an RFC.
Any concerns with Step 1 as a starting PR? It's minimal and non-breaking — URLs that already have
/queryare not affected.I'm happy to start with Step 1 as a PR if the approach looks right, or adjust based on feedback.