Convert the API URL system from an App based one

to a resource based one.

Signed-off-by: Roberto Rosario <roberto.rosario.gonzalez@gmail.com>
This commit is contained in:
Roberto Rosario
2017-05-12 17:53:44 -04:00
parent 105eab0740
commit acdc7dca48
30 changed files with 310 additions and 108 deletions

View File

@@ -0,0 +1,19 @@
from __future__ import unicode_literals
from rest_framework import generics
from rest_api.filters import MayanObjectPermissionsFilter
from rest_api.permissions import MayanPermission
from .classes import APIResource
from .serializers import APIResourceSerializer
class APIResourceTypeListView(generics.ListAPIView):
"""
Returns a list of all the available API resources.
"""
serializer_class = APIResourceSerializer
def get_queryset(self):
return APIResource.all()

View File

@@ -4,9 +4,33 @@ from django.conf.urls import include, url
from django.conf import settings
from django.utils.module_loading import import_string
from .exceptions import APIResourcePatternError
class APIResource(object):
_registry = {}
@classmethod
def all(cls):
return cls._registry.values()
@classmethod
def get(cls, name):
return cls._registry[name]
def __unicode__(self):
return unicode(self.name)
def __init__(self, name, label, description=None):
self.label = label
self.name = name
self.description = description
self.__class__._registry[self.name] = self
class APIEndPoint(object):
_registry = {}
_patterns = []
@classmethod
def get_all(cls):
@@ -46,6 +70,12 @@ class APIEndPoint(object):
def register_urls(self, urlpatterns):
from .urls import urlpatterns as app_urls
app_urls += [
url(r'^%s/' % (self.name or self.app.name), include(urlpatterns)),
]
for url in urlpatterns:
if url.regex.pattern not in self.__class__._patterns:
app_urls.append(url)
self.__class__._patterns.append(url.regex.pattern)
else:
raise APIResourcePatternError(
'App "{}" tried to register API URL pattern "{}", which '
'already exists'.format(self.app.label, url.regex.pattern)
)

View File

@@ -0,0 +1,16 @@
from __future__ import unicode_literals
class APIError(Exception):
"""
Base exception for the API app
"""
pass
class APIResourcePatternError(APIError):
"""
Raised when an app tries to override an existing URL regular expression
pattern
"""
pass

View File

@@ -0,0 +1,9 @@
from __future__ import unicode_literals
from rest_framework import serializers
class APIResourceSerializer(serializers.Serializer):
description = serializers.CharField()
label = serializers.CharField()
name = serializers.CharField()

View File

@@ -2,15 +2,18 @@ from __future__ import unicode_literals
from django.conf.urls import url
from .views import APIBase, APIAppView, BrowseableObtainAuthToken
from .api_views import APIResourceTypeListView
from .views import APIBase, BrowseableObtainAuthToken
urlpatterns = [
]
urlpatterns = []
api_urls = [
url(r'^$', APIBase.as_view(), name='api_root'),
url(r'^api/(?P<path>.*)/?$', APIAppView.as_view(), name='api_app'),
url(
r'^resources/$', APIResourceTypeListView.as_view(),
name='resource-list'
),
url(
r'^auth/token/obtain/$', BrowseableObtainAuthToken.as_view(),
name='auth_token_obtain'

View File

@@ -13,13 +13,6 @@ class APIBase(SwaggerResourcesView):
renderer_classes = (renderers.BrowsableAPIRenderer, renderers.JSONRenderer)
class APIAppView(SwaggerApiView):
"""
Entry points of the selected app.
"""
renderer_classes = (renderers.BrowsableAPIRenderer, renderers.JSONRenderer)
class BrowseableObtainAuthToken(ObtainAuthToken):
"""
Obtain an API authentication token.