Conventions and Good Practices

This document collects conventions and good practices that we are trying to follow when developing HELIPORT.

Construction of URLs

In accordance with the Django docs, we try to maintain a clean and elegant URL scheme.

Most URLs follow the patterns <object type (singular)>/<action or view type>/ or <object type (singular)>/<object id>/<action or view type>/. For viewing a single object, the URL usually does not contain an “action”. E.g.:

urlpatterns = [
    path("project/list/", ProjectListView.as_view()),
    path("project/<int:project>/", ProjectView.as_view()),
    path("project/<int:project>/update/", ProjectUpdateView.as_view()),
]

Keeping the object type and ID in pairs like this makes the URLs understandable for humans and helps keeping them unambiguous and resolvable for Django. Using multiple pairs in a single pattern is also quite common, especially to reference parts of a project, e.g.:

urlpatterns = [
    path("project/<int:project>/archive/<int:archive>/update/", ArchiveView.as_view()),
    path("project/<int:project>/cwl-execution/job/<int:job>/start/", JobStartView.as_view()),
]

The names given to the parameters can often be pk when used with certain generic view classes.

As a word separator, we use hyphens/dashes rather than underscores (or other, possibly URL-encoded characters like spaces). Google recommends hyphens, unfortunately without giving an explanation. Other sources point out hyphens are generally considered separators while underscores are not (see double clicking) and mention improved indexability and search engine optimization as reasons. (The latter two are probably less relevant for HELIPORT.)

For the REST API

When registering view sets in API routers, we follow Django Rest Framework’s example and use the name of the object type in the plural form, e.g.:

router.register(r"projects", ProjectViewSet)
router.register(r"users", UserViewSet)
router.register(r"gate/projects", GateProjectViewSet)

An example for when to deviate from these conventions is when the plural version of the object type is not meaningful, e.g.:

router.register(r"sharelatex", LatexViewSet)