The main building blocks are:
- A web UI where content editors can manage content
- A REST API that delivers published content/data to clients (i.e. websites and apps)
Versioned provides a cost- and time-effective way to manage content via a web UI and to publish it through an API to your websites and applications (and any other clients or systems that need it). Building such a system from scratch takes months of developer time. With Versioned you can be up and running in hours and you also avoid the maintenance burden of custom software.
- Dynamic Content Types - a flexible way for content editors to set up the content types they need without having to do any software development
- Data Validation - content types are a collection of fields and each field has a data type and optionally validation rules to ensure the integrity of the data
- Relationships - a field in a content type can represent a
two-wayrelationship (i.e. link or reference) to another content type and the type of the relationship can be either
- Publishing and Versioning - you can work on new content in a draft state, preview it, and then publish it to clients when it's ready. Content is versioned and you can see what has happened in a publish history.
- Changelog - Versioned maintains a log of changes made to all data so that editors can keep track of exactly what has been changed, when, and by whom
- Webhooks - configure another system to receive an HTTP call whenever content is changed so that your clients always have the latest published content (you may for example need to rebuild a static website when content changes)
- Translations - select which languages to translate your texts into and deliver only the relevant language to your users
Versioned is built on these technologies:
- Models (i.e. database tables). Models are content types that define the structure (or schema) of your data, i.e. which fields you can store, validation rules, and relationships to other models. You may for example have an
Authormodel with the fields
Articlemodel with the fields
Articlecan have a relationship so that an author
has manyarticles and each article
belongs toan author.
- Data (i.e. database rows or documents). Data is the content entered into each model and once it's published it gets delivered as JSON to your clients. Data is stored as documents in a MongoDB database.
- Spaces (i.e. database namespaces). Spaces are isolated collections of models and data and typically represent projects in your organization. A space can be configured to use its own dedicated database.
The REST API
The REST API has two main purposes:
datato be managed (primarily via the web UI). The API also handles
- Delivering published
datato clients. Through the use of a secret API key clients can fetch one or more published documents. Clients have fine grained control over what should be fetched - the number of documents, sorting, filtering, fields, and relationships.
The REST API contains a GraphQL endpoint that allows clients to access the graph of published data in a powerful and efficient way. The recommended way to explore this feature is to use the GraphiQL UI that is linked from the Api page in the Admin UI.
The Admin UI
The Admin UI is where content creators manage
data and make sure
data gets published to clients. The main features are:
- Registration of
models(data types) which are collections of fields and each field has a data type, validation rules (optional), and can represent a relationship to another model
- Managing (creating, updating, deleting)
datafor each model. Data can be versioned and you control when new data (changes) should be published to clients
spaces(or projects) and configuring those spaces. It is highly recommended that you use a dedicated MongoDB database (i.e. with a service like mLab or Compose) and Algolia search service for your spaces especially if you have large amounts of data. Via Heroku Add-Ons you can get access to free MongoDB and Algolia services.
assets, i.e. uploaded files such as images, videos, PDFs etc. This feature is optional and requires that you sign up for a Cloudinary account.
Note that since the web UI is based on the REST API, everything that can be done with the admin UI can also be done directly with the REST API.
There is a publishing life cycle for models with the following states:
Not Yet Published- the document has been created and potentially updated but it has not been published yet
Published- the document is currently published and there are no newer draft versions of the document that are awaiting publication
Draft- the document is published but there is a newer draft version that is awaiting publication
Unpublished- the document was published before but has been unpublished
There is a version history that shows all versions of a document that have been published over time.
Content Delivery to Clients
Content delivery to clients is done with the REST API (or GraphQL) via a CDN (Content Delivery Network) and authentication is handled with an API key. Versioned doesn't come with a built-in CDN and you need to sign up for a service like Fastly, Cloudflare, or CloudFront and use it as a layer between your clients and the Versioned REST API to achieve performance and scalability. Setting up such a CDN should be straightforward and relatively cheap (i.e. Fastly offers 10 million requests per month at 25 USD/month). If you are not using a CDN you can expect the Versioned REST API to be rate limited at around 5 requests per second.
In the Admin UI you will find links to detailed API documentation and example API calls that illustrate how you fetch published data for your clients. Here is an example API call (with httpie) that lists published blog posts:
export BASE_URL=https://api.versioned.io/v1 export SPACE_ID=5ba205c2aefdde0013596636 export MODEL=blog_posts export API_KEY=kf924ed960b74556 http GET "$BASE_URL/data/$SPACE_ID/$MODEL?apiKey=$API_KEY&published=1"
For more fine grained control over which data to fetch you
can use the query parameters
filter. To configure which relationships to fetch (if there are any) use the query parameter
relationshipLevels and optionally one of
graph parameter is more powerful than the
relationships parameter as it controls all fields and not just relationship fields. Please consult the API documentation for more details.
Relationships between models can be unidirectional or bidirectional:
two-wayrelationship connects a field in one model to a field in another model and allows navigation in both directions
one-wayrelationship is a unidirectional link (reference) from a field in a source model to one ore more target models. You can only navigate from the source model to the target models - not in the other direction. There is no field in the target models to represent the relationship.
type of a relationship represents its cardinality (or degree), i.e.
whether at each end of the relationship we have a single reference (ID) or multiple references:
one-to-one- each document in the source model is connected to one document in the target model. The reference in each model is unique.
one-to-many- there are many references (an array) in the source model and a single reference in the target model.
many-to-one- there is a single reference (an ID) in the source model and multiple references in the target model (the inverse of
many-to-many- there are multiple references (an array) in the source model and multiple references in the target model
Versioned has a built-in content type (model) called
assets that allows you to upload files such as images and to reference those files from your models. In order to use this feature you need to sign up for a Cloudinary account and enter your Cloudinary credentials (URL and preset) on the configuration page for your space.
There is an import API endpoint that allows you to create many documents at a time for a model. If you need to write a script to import data there is an example script that you can use as inspiration.