From 828c9f5245acb6fb343e884fa283c996a5b09311 Mon Sep 17 00:00:00 2001 From: lotte-amsterdam Date: Thu, 29 Oct 2026 15:39:20 +0100 Subject: [PATCH 1/5] added record items endpoint with test --- src/dso_api/dynamic_api/routers.py | 13 ++++ src/dso_api/dynamic_api/views/__init__.py | 2 + src/dso_api/dynamic_api/views/ogc.py | 80 +++++++++++++++++++- src/tests/test_dynamic_api/views/test_ogc.py | 49 ++++++++++++ 4 files changed, 143 insertions(+), 1 deletion(-) diff --git a/src/dso_api/dynamic_api/routers.py b/src/dso_api/dynamic_api/routers.py index 58ae28508..34db5eb18 100644 --- a/src/dso_api/dynamic_api/routers.py +++ b/src/dso_api/dynamic_api/routers.py @@ -52,6 +52,7 @@ DatasetMVTView, DatasetTileJSONView, DatasetWFSView, + OGCRecordDetailView, OGCRecordsCollectionDetailView, OGCRecordsCollectionView, viewset_factory, @@ -580,6 +581,18 @@ def _build_ogc_views(self, datasets: Iterable[Dataset]) -> list[URLPattern]: }, ) ) + for version, _ in dataset.schema.versions.items(): + results.append( + path( + f"/ogc/records/collections/{dataset.path}/{version}", + OGCRecordDetailView.as_view(), + name="ogc-record", + kwargs={ + "dataset_name": dataset_id, + "dataset_version": version, + }, + ) + ) return results diff --git a/src/dso_api/dynamic_api/views/__init__.py b/src/dso_api/dynamic_api/views/__init__.py index a447017af..b7103357a 100644 --- a/src/dso_api/dynamic_api/views/__init__.py +++ b/src/dso_api/dynamic_api/views/__init__.py @@ -7,6 +7,7 @@ from .oauth import oauth2_redirect from .ogc import ( OGCIndexView, + OGCRecordDetailView, OGCRecordsCollectionDetailView, OGCRecordsCollectionView, OGCRecordsIndexView, @@ -27,6 +28,7 @@ "OGCRecordsIndexView", "OGCRecordsCollectionView", "OGCRecordsCollectionDetailView", + "OGCRecordDetailView", "DocsIndexView", "oauth2_redirect", "viewset_factory", diff --git a/src/dso_api/dynamic_api/views/ogc.py b/src/dso_api/dynamic_api/views/ogc.py index d4eb66867..8913da15e 100644 --- a/src/dso_api/dynamic_api/views/ogc.py +++ b/src/dso_api/dynamic_api/views/ogc.py @@ -110,13 +110,14 @@ def get(self, request, *args, **kwargs): self.build_record_collection( ds=ds, version=version, + base=base, collection_url=collection_url, ) ) return Response({"records": records}) - def build_record_collection(self, ds, version, collection_url): + def build_record_collection(self, ds, version, base, collection_url): """Handle missing attributes and ensure each OGC field has the expected datatype.""" metadata = { "id": f"{ds.schema.id}_{version}", @@ -137,6 +138,15 @@ def build_record_collection(self, ds, version, collection_url): ], } + for version, _ in ds.schema.versions.items(): + metadata["links"].append( + { + "rel": f"{version}", + "type": "application/json", + "href": f"{base}/v1/ogc/records/collections/{ds.schema.id}/{version}", + } + ) + if ds.schema.get("dateCreated"): metadata["created"] = ds.schema.get("dateCreated") @@ -158,3 +168,71 @@ def build_record_collection(self, ds, version, collection_url): metadata["license"] = ds.schema.license return [metadata] + + +class OGCRecordDetailView(APIView): + """An JSON page for a single OGC record (datasetversion).""" + + renderer_classes = [JSONRenderer] + name = "Record" + + def get_datasets(self): + return [ + ds + for ds in get_active_datasets().db_enabled().order_by("name") + if ds.has_geometry_fields + ] + + def get(self, request, *args, **kwargs): + base = request.build_absolute_uri("/").rstrip("/") + datasets = self.get_datasets() + dataset_name = self.kwargs.get("dataset_name") + dataset_version = self.kwargs.get("dataset_version") + record_url = f"{base}/v1/ogc/records/collections/{dataset_name}/{dataset_version}" + record = [] + + # only some datasets will have a WFS url? + wfs_url = ( + f"{base}/v1/wfs/{dataset_name}/{dataset_version}?service=WFS&request=GetCapabilities" + ) + + ds = next( + (dataset for dataset in datasets if str(dataset.schema.id) == str(dataset_name)), + None, + ) + + record.append( + self.build_record( + ds=ds, + version=dataset_version, + record_url=record_url, + wfs_url=wfs_url, + ) + ) + + return Response({"record": record}) + + def build_record(self, ds, version, record_url, wfs_url): + """Handle missing attributes and ensure each OGC field has the expected datatype.""" + metadata = { + "id": f"{ds.schema.id}_{version}", + "conformsTo": [], + "language": {"code": "nl", "name": "Dutch (Netherlands)"}, + "links": [ + { + "rel": "self", + "type": "application/json", + "href": record_url, + }, + { + "rel": "WFS", + "type": "application/json", + "href": wfs_url, + }, + ], + } + + if ds.schema.get("dateCreated"): + metadata["created"] = ds.schema.get("dateCreated") + + return metadata diff --git a/src/tests/test_dynamic_api/views/test_ogc.py b/src/tests/test_dynamic_api/views/test_ogc.py index 80f113909..3682bd452 100644 --- a/src/tests/test_dynamic_api/views/test_ogc.py +++ b/src/tests/test_dynamic_api/views/test_ogc.py @@ -59,6 +59,16 @@ def test_ogc_view(self, api_client, afval_container): "type": "application/json", "href": "http://testserver/v1/ogc/records/collections/afvalwegingen", }, + { + "rel": "v1", + "type": "application/json", + "href": "http://testserver/v1/ogc/records/collections/afvalwegingen/v1", + }, + { + "rel": "v2", + "type": "application/json", + "href": "http://testserver/v1/ogc/records/collections/afvalwegingen/v2", + }, ], "contacts": [ { @@ -90,6 +100,16 @@ def test_ogc_view(self, api_client, afval_container): "type": "application/json", "href": "http://testserver/v1/ogc/records/collections/afvalwegingen", }, + { + "rel": "v1", + "type": "application/json", + "href": "http://testserver/v1/ogc/records/collections/afvalwegingen/v1", + }, + { + "rel": "v2", + "type": "application/json", + "href": "http://testserver/v1/ogc/records/collections/afvalwegingen/v2", + }, ], "contacts": [ { @@ -104,3 +124,32 @@ def test_ogc_view(self, api_client, afval_container): }, ], } + + +@pytest.mark.django_db +class TestOGCRecordDetailView: + def test_ogc_record_view(self, api_client, afval_container): + ogc_url = "/v1/ogc/records/collections/afvalwegingen/v1" + response = api_client.get(ogc_url) + assert response.status_code == 200, response.content + assert response.data == { + "record": [ + { + "id": "afvalwegingen_v1", + "conformsTo": [], + "language": {"code": "nl", "name": "Dutch (Netherlands)"}, + "links": [ + { + "rel": "self", + "type": "application/json", + "href": "http://testserver/v1/ogc/records/collections/afvalwegingen/v1", + }, + { + "rel": "WFS", + "type": "application/json", + "href": "http://testserver/v1/wfs/afvalwegingen/v1?service=WFS&request=GetCapabilities", + }, + ], + } + ], + } From f56ac6e2887e03e77874d28a7c723ced8e6faa06 Mon Sep 17 00:00:00 2001 From: lotte-amsterdam Date: Thu, 29 Oct 2026 16:37:48 +0100 Subject: [PATCH 2/5] update docs to not include WMS service for records --- src/templates/dso_api/dynamic_api/ogc_records.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/templates/dso_api/dynamic_api/ogc_records.html b/src/templates/dso_api/dynamic_api/ogc_records.html index f8cc63a8a..c0a66b626 100644 --- a/src/templates/dso_api/dynamic_api/ogc_records.html +++ b/src/templates/dso_api/dynamic_api/ogc_records.html @@ -12,7 +12,7 @@ op een gestandaardiseerde manier beschikbaar te stellen. Iedere DSO-dataset wordt ontsloten als een record collection, met metadata over deze dataset uit het Amsterdam Schema en de beschikbare datasetversies. Iedere datasetversie wordt vervolgens beschreven door een afzonderlijk OGC-record met de bijbehorende - metadata en links naar de relevante WFS- en WMS-services. Hierdoor kunnen kaartviewers zoals NL3D en + metadata en links naar de relevante WFS-services. Hierdoor kunnen kaartviewers zoals NL3D en Geosquare deze datasets en datasetversies op een uniforme manier ontdekken en de bijbehorende geografische gegevens raadplegen.

From 050906b4c95b0fca4c1e8969f12aad50e87c16d9 Mon Sep 17 00:00:00 2001 From: lotte-amsterdam Date: Thu, 29 Oct 2026 16:49:38 +0100 Subject: [PATCH 3/5] deleted comment --- src/dso_api/dynamic_api/views/ogc.py | 1 - 1 file changed, 1 deletion(-) diff --git a/src/dso_api/dynamic_api/views/ogc.py b/src/dso_api/dynamic_api/views/ogc.py index 8913da15e..c9c35e69b 100644 --- a/src/dso_api/dynamic_api/views/ogc.py +++ b/src/dso_api/dynamic_api/views/ogc.py @@ -191,7 +191,6 @@ def get(self, request, *args, **kwargs): record_url = f"{base}/v1/ogc/records/collections/{dataset_name}/{dataset_version}" record = [] - # only some datasets will have a WFS url? wfs_url = ( f"{base}/v1/wfs/{dataset_name}/{dataset_version}?service=WFS&request=GetCapabilities" ) From cf6af4f2085a08e0edb5b58343db67fe13ddd1c8 Mon Sep 17 00:00:00 2001 From: lotte-amsterdam Date: Mon, 2 Nov 2026 11:05:08 +0100 Subject: [PATCH 4/5] added /items endpoint + test --- src/dso_api/dynamic_api/routers.py | 13 ++++- src/dso_api/dynamic_api/views/__init__.py | 2 + src/dso_api/dynamic_api/views/ogc.py | 58 ++++++++++++++++++-- src/tests/test_dynamic_api/views/test_ogc.py | 24 ++++++-- 4 files changed, 86 insertions(+), 11 deletions(-) diff --git a/src/dso_api/dynamic_api/routers.py b/src/dso_api/dynamic_api/routers.py index 34db5eb18..101c87e7c 100644 --- a/src/dso_api/dynamic_api/routers.py +++ b/src/dso_api/dynamic_api/routers.py @@ -54,6 +54,7 @@ DatasetWFSView, OGCRecordDetailView, OGCRecordsCollectionDetailView, + OGCRecordsCollectionItemsView, OGCRecordsCollectionView, viewset_factory, ) @@ -581,10 +582,20 @@ def _build_ogc_views(self, datasets: Iterable[Dataset]) -> list[URLPattern]: }, ) ) + results.append( + path( + f"/ogc/records/collections/{dataset.path}/items", + OGCRecordsCollectionItemsView.as_view(), + name="ogc-collections-items", + kwargs={ + "dataset_name": dataset_id, + }, + ) + ) for version, _ in dataset.schema.versions.items(): results.append( path( - f"/ogc/records/collections/{dataset.path}/{version}", + f"/ogc/records/collections/{dataset.path}/items/{version}", OGCRecordDetailView.as_view(), name="ogc-record", kwargs={ diff --git a/src/dso_api/dynamic_api/views/__init__.py b/src/dso_api/dynamic_api/views/__init__.py index b7103357a..40daa1efd 100644 --- a/src/dso_api/dynamic_api/views/__init__.py +++ b/src/dso_api/dynamic_api/views/__init__.py @@ -9,6 +9,7 @@ OGCIndexView, OGCRecordDetailView, OGCRecordsCollectionDetailView, + OGCRecordsCollectionItemsView, OGCRecordsCollectionView, OGCRecordsIndexView, ) @@ -28,6 +29,7 @@ "OGCRecordsIndexView", "OGCRecordsCollectionView", "OGCRecordsCollectionDetailView", + "OGCRecordsCollectionItemsView", "OGCRecordDetailView", "DocsIndexView", "oauth2_redirect", diff --git a/src/dso_api/dynamic_api/views/ogc.py b/src/dso_api/dynamic_api/views/ogc.py index c9c35e69b..11b4d1000 100644 --- a/src/dso_api/dynamic_api/views/ogc.py +++ b/src/dso_api/dynamic_api/views/ogc.py @@ -81,7 +81,7 @@ def get(self, request, *args, **kwargs): class OGCRecordsCollectionDetailView(APIView): - """An JSON page for a single OGC record collection (dataset).""" + """A JSON page for a single OGC record collection (dataset).""" renderer_classes = [JSONRenderer] name = "Records" @@ -143,7 +143,7 @@ def build_record_collection(self, ds, version, base, collection_url): { "rel": f"{version}", "type": "application/json", - "href": f"{base}/v1/ogc/records/collections/{ds.schema.id}/{version}", + "href": f"{base}/v1/ogc/records/collections/{ds.schema.id}/items/{version}", } ) @@ -170,8 +170,58 @@ def build_record_collection(self, ds, version, base, collection_url): return [metadata] +class OGCRecordsCollectionItemsView(APIView): + """Shows a JSON page with an overview of record collection items.""" + + renderer_classes = [JSONRenderer] + name = "Collection Items" + + def get_datasets(self): + return [ + ds + for ds in get_active_datasets().db_enabled().order_by("name") + if ds.has_geometry_fields + ] + + def get(self, request, *args, **kwargs): + base = request.build_absolute_uri("/").rstrip("/") + datasets = self.get_datasets() + dataset_name = self.kwargs.get("dataset_name") + + ds = next( + (dataset for dataset in datasets if str(dataset.schema.id) == str(dataset_name)), + None, + ) + + items = [] + + for version, _ in ds.schema.versions.items(): + items.append( + { + "id": f"{ds.schema.id}_{version}", + "title": ds.schema.title or ds.name, + "description": ds.schema.description or "", + "links": [ + { + "rel": "self", + "type": "application/json", + "href": (f"{base}/v1/ogc/records/collections/{ds.schema.id}/items"), + }, + { + "rel": f"{version}", + "type": "application/json", + "href": f"{base}/v1/ogc/records/collections/{ds.schema.id}/items" + f"/{version}", + }, + ], + } + ) + + return Response({"items": items}) + + class OGCRecordDetailView(APIView): - """An JSON page for a single OGC record (datasetversion).""" + """A JSON page for a single OGC record (datasetversion).""" renderer_classes = [JSONRenderer] name = "Record" @@ -188,7 +238,7 @@ def get(self, request, *args, **kwargs): datasets = self.get_datasets() dataset_name = self.kwargs.get("dataset_name") dataset_version = self.kwargs.get("dataset_version") - record_url = f"{base}/v1/ogc/records/collections/{dataset_name}/{dataset_version}" + record_url = f"{base}/v1/ogc/records/collections/{dataset_name}/items/{dataset_version}" record = [] wfs_url = ( diff --git a/src/tests/test_dynamic_api/views/test_ogc.py b/src/tests/test_dynamic_api/views/test_ogc.py index 3682bd452..3310bf6f1 100644 --- a/src/tests/test_dynamic_api/views/test_ogc.py +++ b/src/tests/test_dynamic_api/views/test_ogc.py @@ -62,12 +62,12 @@ def test_ogc_view(self, api_client, afval_container): { "rel": "v1", "type": "application/json", - "href": "http://testserver/v1/ogc/records/collections/afvalwegingen/v1", + "href": "http://testserver/v1/ogc/records/collections/afvalwegingen/items/v1", }, { "rel": "v2", "type": "application/json", - "href": "http://testserver/v1/ogc/records/collections/afvalwegingen/v2", + "href": "http://testserver/v1/ogc/records/collections/afvalwegingen/items/v2", }, ], "contacts": [ @@ -103,12 +103,12 @@ def test_ogc_view(self, api_client, afval_container): { "rel": "v1", "type": "application/json", - "href": "http://testserver/v1/ogc/records/collections/afvalwegingen/v1", + "href": "http://testserver/v1/ogc/records/collections/afvalwegingen/items/v1", }, { "rel": "v2", "type": "application/json", - "href": "http://testserver/v1/ogc/records/collections/afvalwegingen/v2", + "href": "http://testserver/v1/ogc/records/collections/afvalwegingen/items/v2", }, ], "contacts": [ @@ -126,10 +126,22 @@ def test_ogc_view(self, api_client, afval_container): } +@pytest.mark.django_db +class TestOGCRecordsCollectionItemsView: + def test_ogc_items_view(self, api_client, afval_container): + ogc_url = "/v1/ogc/records/collections/afvalwegingen/items" + response = api_client.get(ogc_url) + json = response.json() + assert response.status_code == 200, response.content + assert len(json["items"]) == 2 + assert json["items"][0]["id"] == "afvalwegingen_v1" + assert json["items"][1]["id"] == "afvalwegingen_v2" + + @pytest.mark.django_db class TestOGCRecordDetailView: def test_ogc_record_view(self, api_client, afval_container): - ogc_url = "/v1/ogc/records/collections/afvalwegingen/v1" + ogc_url = "/v1/ogc/records/collections/afvalwegingen/items/v1" response = api_client.get(ogc_url) assert response.status_code == 200, response.content assert response.data == { @@ -142,7 +154,7 @@ def test_ogc_record_view(self, api_client, afval_container): { "rel": "self", "type": "application/json", - "href": "http://testserver/v1/ogc/records/collections/afvalwegingen/v1", + "href": "http://testserver/v1/ogc/records/collections/afvalwegingen/items/v1", }, { "rel": "WFS", From c500596da3edfe74409ac091e2f83d353616b364 Mon Sep 17 00:00:00 2001 From: lotte-amsterdam Date: Mon, 2 Nov 2026 12:54:00 +0100 Subject: [PATCH 5/5] changed after review --- src/dso_api/dynamic_api/routers.py | 2 +- src/dso_api/dynamic_api/views/ogc.py | 36 ++++++++------- src/tests/test_dynamic_api/views/test_ogc.py | 46 ++++++++++---------- 3 files changed, 44 insertions(+), 40 deletions(-) diff --git a/src/dso_api/dynamic_api/routers.py b/src/dso_api/dynamic_api/routers.py index 101c87e7c..13cc570fd 100644 --- a/src/dso_api/dynamic_api/routers.py +++ b/src/dso_api/dynamic_api/routers.py @@ -595,7 +595,7 @@ def _build_ogc_views(self, datasets: Iterable[Dataset]) -> list[URLPattern]: for version, _ in dataset.schema.versions.items(): results.append( path( - f"/ogc/records/collections/{dataset.path}/items/{version}", + f"/ogc/records/collections/{dataset.path}/items/{dataset_id}_{version}", OGCRecordDetailView.as_view(), name="ogc-record", kwargs={ diff --git a/src/dso_api/dynamic_api/views/ogc.py b/src/dso_api/dynamic_api/views/ogc.py index 11b4d1000..4f012f7da 100644 --- a/src/dso_api/dynamic_api/views/ogc.py +++ b/src/dso_api/dynamic_api/views/ogc.py @@ -1,5 +1,6 @@ import logging +from django.utils.functional import cached_property from django.views.generic import TemplateView from rest_framework.renderers import JSONRenderer from rest_framework.response import Response @@ -48,6 +49,7 @@ class OGCRecordsCollectionView(APIView): renderer_classes = [JSONRenderer] name = "Record Collections" + @cached_property def get_datasets(self): return [ ds @@ -57,7 +59,7 @@ def get_datasets(self): def get(self, request, *args, **kwargs): base = request.build_absolute_uri("/").rstrip("/") - datasets = self.get_datasets() + datasets = self.get_datasets collections = [] @@ -86,6 +88,7 @@ class OGCRecordsCollectionDetailView(APIView): renderer_classes = [JSONRenderer] name = "Records" + @cached_property def get_datasets(self): return [ ds @@ -95,7 +98,7 @@ def get_datasets(self): def get(self, request, *args, **kwargs): base = request.build_absolute_uri("/").rstrip("/") - datasets = self.get_datasets() + datasets = self.get_datasets dataset_name = self.kwargs.get("dataset_name") collection_url = f"{base}/v1/ogc/records/collections/{dataset_name}" records = [] @@ -143,7 +146,8 @@ def build_record_collection(self, ds, version, base, collection_url): { "rel": f"{version}", "type": "application/json", - "href": f"{base}/v1/ogc/records/collections/{ds.schema.id}/items/{version}", + "href": f"{base}/v1/ogc/records/collections/{ds.schema.id}/items" + f"/{ds.schema.id}_{version}", } ) @@ -176,6 +180,7 @@ class OGCRecordsCollectionItemsView(APIView): renderer_classes = [JSONRenderer] name = "Collection Items" + @cached_property def get_datasets(self): return [ ds @@ -185,7 +190,7 @@ def get_datasets(self): def get(self, request, *args, **kwargs): base = request.build_absolute_uri("/").rstrip("/") - datasets = self.get_datasets() + datasets = self.get_datasets dataset_name = self.kwargs.get("dataset_name") ds = next( @@ -211,7 +216,7 @@ def get(self, request, *args, **kwargs): "rel": f"{version}", "type": "application/json", "href": f"{base}/v1/ogc/records/collections/{ds.schema.id}/items" - f"/{version}", + f"/{ds.schema.id}_{version}", }, ], } @@ -226,6 +231,7 @@ class OGCRecordDetailView(APIView): renderer_classes = [JSONRenderer] name = "Record" + @cached_property def get_datasets(self): return [ ds @@ -235,11 +241,13 @@ def get_datasets(self): def get(self, request, *args, **kwargs): base = request.build_absolute_uri("/").rstrip("/") - datasets = self.get_datasets() + datasets = self.get_datasets dataset_name = self.kwargs.get("dataset_name") dataset_version = self.kwargs.get("dataset_version") - record_url = f"{base}/v1/ogc/records/collections/{dataset_name}/items/{dataset_version}" - record = [] + record_url = ( + f"{base}/v1/ogc/records/collections/{dataset_name}/items" + f"/{dataset_name}_{dataset_version}" + ) wfs_url = ( f"{base}/v1/wfs/{dataset_name}/{dataset_version}?service=WFS&request=GetCapabilities" @@ -250,13 +258,11 @@ def get(self, request, *args, **kwargs): None, ) - record.append( - self.build_record( - ds=ds, - version=dataset_version, - record_url=record_url, - wfs_url=wfs_url, - ) + record = self.build_record( + ds=ds, + version=dataset_version, + record_url=record_url, + wfs_url=wfs_url, ) return Response({"record": record}) diff --git a/src/tests/test_dynamic_api/views/test_ogc.py b/src/tests/test_dynamic_api/views/test_ogc.py index 3310bf6f1..edf95d20b 100644 --- a/src/tests/test_dynamic_api/views/test_ogc.py +++ b/src/tests/test_dynamic_api/views/test_ogc.py @@ -62,12 +62,12 @@ def test_ogc_view(self, api_client, afval_container): { "rel": "v1", "type": "application/json", - "href": "http://testserver/v1/ogc/records/collections/afvalwegingen/items/v1", + "href": "http://testserver/v1/ogc/records/collections/afvalwegingen/items/afvalwegingen_v1", }, { "rel": "v2", "type": "application/json", - "href": "http://testserver/v1/ogc/records/collections/afvalwegingen/items/v2", + "href": "http://testserver/v1/ogc/records/collections/afvalwegingen/items/afvalwegingen_v2", }, ], "contacts": [ @@ -103,12 +103,12 @@ def test_ogc_view(self, api_client, afval_container): { "rel": "v1", "type": "application/json", - "href": "http://testserver/v1/ogc/records/collections/afvalwegingen/items/v1", + "href": "http://testserver/v1/ogc/records/collections/afvalwegingen/items/afvalwegingen_v1", }, { "rel": "v2", "type": "application/json", - "href": "http://testserver/v1/ogc/records/collections/afvalwegingen/items/v2", + "href": "http://testserver/v1/ogc/records/collections/afvalwegingen/items/afvalwegingen_v2", }, ], "contacts": [ @@ -141,27 +141,25 @@ def test_ogc_items_view(self, api_client, afval_container): @pytest.mark.django_db class TestOGCRecordDetailView: def test_ogc_record_view(self, api_client, afval_container): - ogc_url = "/v1/ogc/records/collections/afvalwegingen/items/v1" + ogc_url = "/v1/ogc/records/collections/afvalwegingen/items/afvalwegingen_v1" response = api_client.get(ogc_url) assert response.status_code == 200, response.content assert response.data == { - "record": [ - { - "id": "afvalwegingen_v1", - "conformsTo": [], - "language": {"code": "nl", "name": "Dutch (Netherlands)"}, - "links": [ - { - "rel": "self", - "type": "application/json", - "href": "http://testserver/v1/ogc/records/collections/afvalwegingen/items/v1", - }, - { - "rel": "WFS", - "type": "application/json", - "href": "http://testserver/v1/wfs/afvalwegingen/v1?service=WFS&request=GetCapabilities", - }, - ], - } - ], + "record": { + "id": "afvalwegingen_v1", + "conformsTo": [], + "language": {"code": "nl", "name": "Dutch (Netherlands)"}, + "links": [ + { + "rel": "self", + "type": "application/json", + "href": "http://testserver/v1/ogc/records/collections/afvalwegingen/items/afvalwegingen_v1", + }, + { + "rel": "WFS", + "type": "application/json", + "href": "http://testserver/v1/wfs/afvalwegingen/v1?service=WFS&request=GetCapabilities", + }, + ], + }, }