← Back to Blog

How to Publish WFS Services with GeoServer

Learn how to complete a GeoServer WFS setup — from workspace creation to publishing layers, CQL filtering, and connecting Leaflet or OpenLayers clients.

A GeoServer WFS setup gives you a standards-based way to serve vector geospatial data over HTTP. WFS (Web Feature Service) is an OGC standard that lets clients query, filter, and retrieve geographic features as GeoJSON, GML, or other formats. Whether you are building an internal asset management system or a public-facing map portal, GeoServer provides a production-ready WFS implementation that works with PostGIS, Shapefiles, GeoPackage, and dozens of other data stores. This guide walks through every step — from installing GeoServer to connecting a Leaflet client to your new WFS endpoint.

Prerequisites for GeoServer WFS Setup

GeoServer is a Java application that runs inside a servlet container. You need a Java Runtime Environment (JRE) version 11 or later — OpenJDK works well. The standalone installer bundles Jetty, so no separate Tomcat installation is required for development. Download the latest stable release from the GeoServer installation documentation and verify your Java version before proceeding.

# Verify Java is installed
java -version

# Unpack and start GeoServer (Linux/macOS)
unzip geoserver-2.26.0-bin.zip -d /opt/geoserver
export GEOSERVER_HOME=/opt/geoserver
cd $GEOSERVER_HOME
./bin/startup.sh

Once started, open http://localhost:8080/geoserver in your browser. The default credentials are admin / geoserver. Change these immediately in any environment beyond local development.

Creating a Workspace

Workspaces act as namespaces that organize your layers and services. Navigate to Data → Workspaces → Add new workspace. Enter a short name such as geodemo and a namespace URI like http://geodemo.example.com. The namespace URI does not need to resolve — it is an identifier used in XML responses. Tick the WFS checkbox under the services section so the workspace is enabled for WFS requests.

Keeping workspaces focused — one per project or department — makes it easier to manage service-level security policies and virtual OWS endpoints later on.

Adding a Data Store

A data store tells GeoServer where your source data lives. Go to Data → Stores → Add new Store and choose the appropriate type. For a Shapefile, select Shapefile and browse to the .shp path. For PostGIS, select PostGIS and fill in the host, port, database, schema, user, and password fields. GeoServer validates the connection before saving, so double-check credentials if it fails.

# Example PostGIS connection parameters
Host:     localhost
Port:     5432
Database: gis_data
Schema:   public
User:     geouser
Password: ********

Once the store is saved, GeoServer scans available tables or files and presents them for publishing. You can configure multiple stores inside a single workspace to aggregate data from different backends.

Publishing a Layer as WFS

From the new store page, click Publish next to the layer you want to expose. GeoServer opens the layer editor with two tabs: Data and Publishing. On the Data tab, confirm the declared SRS — for most web mapping use cases this should be EPSG:4326, which uses longitude and latitude in degrees. Click Compute from data and Compute from native bounds to populate the bounding box fields automatically.

On the Publishing tab, ensure that WFS is listed among the enabled service types. Save the layer. Your data is now available through the WFS endpoint at a URL like /geoserver/geodemo/wfs. Understanding coordinate reference systems is critical here — read our guide on EPSG:4326 vs EPSG:3857 if you are unsure which projection to declare.

Configuring Projections and Reprojection

GeoServer can reproject data on the fly. If your source data is stored in a projected CRS such as EPSG:32632 (UTM Zone 32N) but you want to serve it in EPSG:4326, set the native SRS to the source CRS and the declared SRS to 4326. Choose Reproject native to declared under the SRS handling dropdown. Clients can also request a specific CRS per request using the srsName parameter in GetFeature calls.

This flexibility means you do not need to maintain duplicate datasets in different projections. GeoServer handles the math at request time, although heavy reprojection on large responses can add latency.

Testing with GetCapabilities

The GetCapabilities request is the first thing any WFS client sends. It returns an XML document describing available layers, supported operations, output formats, and filter capabilities. Test it by opening this URL in your browser:

http://localhost:8080/geoserver/geodemo/wfs?service=WFS&version=2.0.0&request=GetCapabilities

Look for your layer name inside the <FeatureTypeList> element. If it is missing, go back to the layer editor and verify that WFS is enabled for the workspace and the layer bounding box is populated.

Retrieving Features with GetFeature

GetFeature is the primary operation for pulling data from a WFS. By default GeoServer returns GML, but you can request GeoJSON by setting the output format parameter. This is usually the best choice for web applications because it can be consumed directly by JavaScript without any XML parsing.

# Request all features as GeoJSON
http://localhost:8080/geoserver/geodemo/wfs?
  service=WFS&
  version=2.0.0&
  request=GetFeature&
  typeNames=geodemo:buildings&
  outputFormat=application/json

# Limit results
&count=50

The response is a standard GeoJSON FeatureCollection. You can paste it directly into GeoDataTools to visualize it on an interactive map, inspect feature properties, or convert it to KML for use in Google Earth.

Filtering with CQL_FILTER

GeoServer extends standard WFS filtering with CQL (Common Query Language), which is far more readable than the XML-based OGC Filter. Append a CQL_FILTER parameter to your GetFeature request to retrieve only the features you need.

# Attribute filter
CQL_FILTER=status='active' AND area_sqm > 500

# Spatial filter — features within a bounding box
CQL_FILTER=BBOX(geom, -74.05, 40.68, -73.90, 40.85)

# Combining spatial and attribute filters
CQL_FILTER=INTERSECTS(geom, POINT(-73.98 40.75)) AND type='commercial'

CQL supports comparison operators, logical operators, spatial predicates like INTERSECTS, WITHIN, and DWITHIN, as well as functions for string matching and date ranges. Server-side filtering reduces payload size dramatically, which matters when serving data to bandwidth-constrained mobile clients.

Security Considerations

GeoServer ships with a role-based access control system. At minimum, change the default admin password and create separate roles for read-only WFS consumers. Navigate to Security → Data to set per-workspace or per-layer rules that restrict which roles can read or write features through WFS-T (transactional WFS).

  • Disable WFS-T unless you explicitly need clients to insert, update, or delete features.
  • Enable CORS in the web.xml if your WFS will be called from browser-based applications on different domains.
  • Use HTTPS in production — place GeoServer behind a reverse proxy like Nginx or Apache with TLS termination.
  • Limit request sizes by setting maxFeatures defaults on each layer to prevent accidental full-table dumps.

For public-facing services, consider adding rate limiting at the reverse proxy layer to protect against denial-of-service through expensive spatial queries.

Connecting from Leaflet and OpenLayers

Once your WFS endpoint is live, connecting from a client library is straightforward. In Leaflet, fetch the GeoJSON endpoint and add it to the map:

fetch('https://your-server.com/geoserver/geodemo/wfs?' +
  'service=WFS&version=2.0.0&request=GetFeature' +
  '&typeNames=geodemo:buildings&outputFormat=application/json')
  .then(res => res.json())
  .then(data => {
    L.geoJSON(data, {
      style: { color: '#3388ff', weight: 1 }
    }).addTo(map);
  });

In OpenLayers, use the built-in WFS format loader which handles pagination and CRS negotiation automatically. Both libraries support dynamic reloading when the map extent changes, allowing you to implement a "load features in view" pattern that keeps client-side memory usage manageable.

For comparing formats before deciding how to serve your data, see our detailed breakdown of GeoJSON vs KML.

Performance Tips

  • Add spatial indexes in PostGIS (CREATE INDEX ... USING GIST) — GeoServer relies on them for fast bounding-box queries.
  • Enable GeoServer caching with GeoWebCache for layers that change infrequently.
  • Use propertyName to request only the columns you need, reducing serialization overhead.
  • Paginate large responses with startIndex and count parameters instead of fetching everything at once.

FAQ

What output formats does GeoServer WFS support?

GeoServer supports GML 2, GML 3, GeoJSON, CSV, and Shapefile as WFS output formats out of the box. Additional formats can be added through community extensions. For web applications, outputFormat=application/json returns a standard GeoJSON FeatureCollection that any JavaScript mapping library can consume directly.

Can I use WFS with authentication?

Yes. GeoServer supports HTTP Basic authentication, digest authentication, and integration with external identity providers through its security subsystem. You can restrict specific layers or workspaces to authenticated roles only, and clients pass credentials in the standard HTTP Authorization header with each request.

How is WFS different from WMS?

WMS returns pre-rendered map images (PNG or JPEG tiles), while WFS returns the actual vector feature data — geometries and attribute values. WFS is the right choice when clients need to query, filter, or style features dynamically. WMS is better when you need fast rendering of large datasets without transferring raw geometry to the browser.

Conclusion

A well-configured GeoServer WFS setup unlocks powerful, standards-compliant vector data services for any web or desktop GIS client. From creating workspaces and stores to filtering with CQL and securing endpoints, the workflow is methodical but manageable. Once your WFS is live, tools like GeoDataTools make it easy to visualize, inspect, and convert the GeoJSON responses without writing any code.

Ready to work with your geospatial data?

Visualize, filter, and convert GeoJSON and KML files directly in your browser.

Try GeoDataTools