Apparat URL Design
All objects published via apparat are assigned unique permanent URLs for access and retrieval. As apparat aims to impose as few requirements as possible, URLs need to be designed deliberately. In particular, object URLs SHOULD NOT depend on
- a routing mechanism,
- the web server's index document feature¹,
- symbolic links or
- interpreters of any kind.
Canonical object URLs widely adhere to the underlying file system and should be easily resolvable even without a web server.
- Alternative approach: File formats and extensions are implementation details that don't have to be transparent to the client. It is OK to use the web server layer to abstract away these details (and rely on the web server's rewrite features).
Object URLs
There's no really compelling reason to distribute the entirety of objects over a multi-level directory structure. Doing so, however,
- makes it easier to manually find a specific object in the file system,
- keeps up the file system performance and
- helps avoiding troubles with file and directory name length limitations under certain file systems.
A typical apparat object URL looks like this:
https://apparat.tools/2015/10/01/36704.event/36704
It consists of
- a base URL associated with the apparat instance as a whole (
https://apparat.tools/), - a repository URL identifying the repository the object belongs to (might be empty),
- up to six nested subdirectories denoting the object's creation date (and time), configurable from
YYYY/MM/DDtoYYYY/MM/DD/HH/II/SS, - an innermost directory named after the object ID and the object type, serving as parent directory for all object related files,
- and finally the object name itself, consisting of the original object file name (media objects only), the object ID an optionally an object revision number.
https://apparat.tools / blog / 2015/10/01 / 36704 . image / 36704 - 2
^ ^ ^ ^ ^ ^ ^
base URL repository creation object object object object
URL date ID type ID revision
Base URL
The base URL associated with an apparat instance MAY inlude login credentials, a port number and / or a path component (e.g. http://user:password@example.com:80/objects/). In general, the HTTPS scheme is preferred for apparat URLs.
Repository URL
The repository URL identifies the repository an object belongs to. It is relative to the apparat base URL and typically reflects subdirectories in the file system (e.g. blog). It might be empty (in which case no subdirectories are involved). In practice it depends on your repository configuration which part of the object URL is considered the repository URL (if any) or the path part of the apparat base URL instead.
Creation Date
Using creation dates for structuring a large number of objects seems to be an intuitive and the most widely accepted approach. These dates are immutable, and unlike many other category systems the calendar is a pretty stable, predictable and commonly understood system. Although ordinal dates would be slightly shorter, apparat sticks to a Gregorian date representation as the large majority of users is not familiar with ordinal dates at all.
Object IDs
It is possible that several objects are created simultaneously (in terms of the date precision in use). In order to unambiguously distinguish these objects by URL they need to be numbered sequentially in some way. While it may be possible to interpret the preceding date based URL part by intuition, any form of abstract numbering will be of little cognitive value to users. So instead of numbering the objects "locally" (within the scope of their particular creation date and time), apparat applies a "global" numbering across all objects, turning the necessity into a feature. The absolute object creation order will always be comprehensible regardless of the creation dates.
The object ID is used as the first part of the object's parent directory and once more as (a suffix to) the object name.
Question: Naturally sorting files by object ID?
Object types
Please see the object summary for a list of known object types.
Object names
Text objects
A text based object (e.g. an article, note, etc.) results from a raw text submission, so the object resource is created from scratch. The object name is built from
- the automatically assigned object ID and
- an optional revision number, separated by a dash.
An example could be 36704-1. The object resource will be saved using a lower-case .md (Markdown) file extension and also include a language indicator.
Media objects
In contrast, a media object (e.g. an image, video, etc.) derives from an existing file that is submitted during publication. As the original file name might describe the object's contents and thus be of a certain value to users, it is preserved, yet normalized to comply with general URL requirements. The object name is built from
- the normalized original file name (without the file extension),
- the automatically assigned object ID and finally
- an optional revision number, separated by a dash.
An example could be myphoto.36704-2. The media file will be saved with its original lower-case file extension and also include a language indicator.
Object revision
When an object gets modified and re-published, apparat saves a copy of the previous instance instead of simply overwriting it with the updated version. The latest instance will always be accessible under the canonical object URL, with the current version number being part of the object meta data. Previous versions may be explicitely retrieved by inserting a version identifier into the object URL (as a suffix of the object ID):
https://apparat.tools/2015/10/01/36704.event/36704-1.md
Identifier for version 1 ^^
Apparat's versioning system is explained in detail here.
Object resources
Object resources use the object name as first part of their file name, followed by a lower-case file extension.
/2015/10/01/36704.image/ 36704 - 2 . md
^ ^ ^
object object file
ID revision extension
File extensions
As recommended a canonical object URL doesn't use a file extension since the file format (which is what file extensions usually indicate) is an implementation detail that shouldn't be mandatory for accessing and retrieving the object. When manually resolving an object URL, it will be easy to find the corresponding file as there will be no other file in the same directory with the very same name part. When resolving the URL via a web server, content negotiation should be used. The object type (also part of the object URL) will support the negotiation process.
A word on ...
Object localizations
In general, localized object versions are considered as completely separate objects with independent URLs, creation dates and revisions. There should be cross-references between localizations that preferably support content negotiation (TBD).
Object references
Some properties support apparat object references as values (e.g. meta.authors). References to objects
- within the same apparat instance take the form of root relative URLs, e.g.
/2015/10/01/36704.event/36704for an object in the same repository or/repo/2015/10/01/36704.event/36704for an object in another registered repository (with the repository URLrepoin this case)- of remote apparat instances use the custom protocol
aprt(respectivelyaprts) to distiguish them from regular HTTP URLs and trigger object instantiation (e.g.aprts://apparat.tools/2015/10/01/36704.event/36704).