geosolutions-it / geonode-mapstore-client

MapStore Client for GeoNode
Other
2 stars 131 forks source link

New GeoNode REST API design #189

Closed giohappy closed 3 years ago

giohappy commented 4 years ago

GeoNode API v2 - Technical Proposal

We would like to create and document full CRUD REST APIs for GeoNode.

Pre-requisites and assumptions

Technical Proposal

Code prototype here: https://github.com/GeoNode/geonode/tree/rest_api_v2_proof_of_concept

The module geonode.api introduces a new router = routers.DynamicRouter()

The module geonode.base.api provides the default ResourceBase serializers and paginator other than basic serializer for base GeoNode types.

Whenever we would need to extend the APIs on a new module, we can follow the approach below (example for Layers):

  1. Create a new submodule <app_label>.api
  2. Extend the <app_label>.urls with the REST endpoint extension name (e.g.url(r'^', include('geonode.layers.api.urls')))
  3. Attach the routes to <app_label>.api.urls by inheriting the router = routers.DynamicRouter() from the geonode.api module, e.g.:
    from geonode.api.urls import router
    from . import views
    router.register(r'layers', views.LayerViewSet)
  4. Whenever we need to serialize a new instance of geonode.base.ResourceBase we could easily extend the ResourceBaseSerializer e.g.:

    class LayerSerializer(ResourceBaseSerializer):
    
        def __init__(self, *args, **kwargs):
            # Instantiate the superclass normally
            super(LayerSerializer, self).__init__(*args, **kwargs)
    
        class Meta:
            model = Layer
            name = 'layer'
            fields = (
                'pk', 'uuid', 'name',
                'workspace', 'store', 'storeType', 'charset',
                'is_mosaic', 'has_time', 'has_elevation', 'time_regex', 'elevation_regex',
                'use_featureinfo_custom_template', 'featureinfo_custom_template',
                'default_style', 'styles', 'attribute_set'
            )
    
        name = serializers.CharField(read_only=True)
        workspace = serializers.CharField(read_only=True)
        store = serializers.CharField(read_only=True)
        storeType = serializers.CharField(read_only=True)
        charset = serializers.CharField(read_only=True)
    
        default_style = DynamicRelationField(StyleSerializer, embed=True, many=False, read_only=True)
        styles = DynamicRelationField(StyleSerializer, embed=True, many=True, read_only=True)
    
        attribute_set = DynamicRelationField(AttributeSerializer, embed=True, many=True, read_only=True)

    Notice that we don't need to serialize again all the ResourceBase fields. They will be inherited from the ResourceBaseSerializer

Outcome:

image

A&A

Currently we defined a sample custom permission class geonode.base.api.permissions.IsOwnerOrReadOnly which assigns read/write permissions to admin or owners of the resource.

Similarly, we could extend or define further permissions classes baing able to assign permissions to the resources accordingly to a specific workflow logic.

Documentation

Official API documentation will be maintained through Swagger.io

image

Whenever the YAML will be fully defined, it can be easily attached to official GeoNode docs through the sphinxcontrib-openapi module extension.

giohappy commented 4 years ago

@afabiani I report here what I wrote inside the issue for Almaviva. I wouldn't adopt dynamic-rest. Even if understand the felxibility they provide they're toof ar from standard REST API structures. I would rather consider a nested structure, where nested endpoints provide additional response for a given resource (e.g. users/1/layers to obtain the layers for user 1, etc.).

giohappy commented 4 years ago

@afabiani for the creation of the OpenAPI spec I would consider drf-yasg to automate the creation and keep the it aligned/inlined with the code.

giohappy commented 4 years ago

/remind me to send a document with Work Packages for the REST API tender from Thunen the 21st September, 2020

reminders[bot] commented 4 years ago

@giohappy set a reminder for Sep 21st 2020

reminders[bot] commented 4 years ago

:wave: @giohappy, send a document with Work Packages for the REST API tender from Thunen the