A CMS REST API on MongoDB and Node.js.
Documentation is available at versioned-doc
A hosted and managed version of this API is available at versioned.io
export NODE_PATH=.
npm install
The api requires the Algolia env variables to be set:
export ALGOLIASEARCH_API_KEY=...
export ALGOLIASEARCH_API_KEY_SEARCH=...
export ALGOLIASEARCH_APPLICATION_ID=...
LOG_LEVEL=verbose npm run dev
Run linting, unit tests, and api tests:
npm test
Quiet mode:
LOG_LEVEL=error npm test
Verbose mode:
LOG_LEVEL=verbose npm test
export BASE_URL=http://localhost:3000/v1
Create user:
echo '{"name": "Admin User", "email": "[email protected]", "password": "admin"}' | http POST $BASE_URL/users
export USER_ID=...
Make super user:
mongo versioned2_development
db.users.update({_id: '$USER_ID'}, {$set: {superUser: true}})
Login:
echo '{"email": "[email protected]", "password": "admin"}' | http POST $BASE_URL/login
export TOKEN=...
Create account:
echo '{"name": "My CMS"}' | http POST $BASE_URL/accounts Authorization:"Bearer $TOKEN"
export ACCOUNT_ID=...
export SPACE_ID=...
Create Published Model in Space:
echo "{\"name\": \"Published Items\", \"spaceId\": \"${SPACE_ID}\", \"coll\": \"items\", \"features\": [\"published\"], \"model\": {\"schema\": {\"type\": \"object\", \"properties\": {\"title\": {\"type\": \"string\"}, \"key\": {\"type\": \"string\", \"x-meta\": {\"update\": false}}}}}}" | http POST $BASE_URL/$SPACE_ID/models Authorization:"Bearer $TOKEN"
Create some content for that model:
http POST $BASE_URL/data/$SPACE_ID/items Authorization:"Bearer $TOKEN" title="My first item"
List content:
http $BASE_URL/data/$SPACE_ID/items Authorization:"Bearer $TOKEN"
http "$BASE_URL/data/$SPACE_ID/items?published=1" Authorization:"Bearer $TOKEN"
Get account:
http $BASE_URL/accounts/$ACCOUNT_ID?relationshipLevels=1 Authorization:"Bearer $TOKEN"
Get spaces:
http $BASE_URL/$ACCOUNT_ID/spaces?relationshipLevels=1 Authorization:"Bearer $TOKEN"
Get user:
http $BASE_URL/users/$USER_ID?relationshipLevels=2 Authorization:"Bearer $TOKEN"
Set defaultSpaceId for user:
echo "{\"defaultSpaceId\": \"$SPACE_ID\"}" | http PUT $BASE_URL/users/$USER_ID Authorization:"Bearer $TOKEN"
http $BASE_URL/users/$USER_ID?relationshipLevels=2 Authorization:"Bearer $TOKEN"
Import content:
echo '{"docs": [{"title": "foo"}, {"title": "bar"}]}' | http post $BASE_URL/data/$SPACE_ID/import/items Authorization:"Bearer $TOKEN"
Example of command line data fetching, publishing, and versioning with curl
and jq:
export [email protected]
export VERSIONED_PASSWORD=...
export BASE_URL=http://localhost:3000/v1
# Login
export LOGIN_DATA=$(curl -X POST -H "Content-Type: application/json" -d "{\"email\": \"$VERSIONED_EMAIL\", \"password\": \"$VERSIONED_PASSWORD\"}" $BASE_URL/login?getUser=1)
export AUTH_TOKEN=$(echo $LOGIN_DATA | jq --raw-output .data.token) # token for admin usage
export AUTH="Authorization: Bearer $AUTH_TOKEN"
export ACCOUNT_ID=$(echo $LOGIN_DATA | jq --raw-output .data.user.accounts[0].id)
# List spaces
curl -H "$AUTH" $BASE_URL/$ACCOUNT_ID/spaces
# Get space id by name
export SPACE=$(curl -H "$AUTH" $BASE_URL/$ACCOUNT_ID/spaces?filter.name=Aftonbladet | jq --raw-output .data[0])
export SPACE_ID=$(echo $SPACE | jq --raw-output .id)
export API_KEY=$(echo $SPACE | jq --raw-output .apiKey) # token for clients to fetch published content
# List models in space and output only a few properties
curl -H "$AUTH" "$BASE_URL/$SPACE_ID/models?graph=name,coll,external,features"
# Show data stats for models in space (number of documents per model etc.)
curl -H "$AUTH" "$BASE_URL/$SPACE_ID/dbStats.json"
# List data for a model
curl -H "$AUTH" $BASE_URL/data/$SPACE_ID/sections_metadata
# List data with invalid query param yields error with list of valid params
curl -H "$AUTH" $BASE_URL/data/$SPACE_ID/sections_metadata?foo=bar
# List data with sort (default sort is updatedAt descending)
curl -H "$AUTH" $BASE_URL/data/$SPACE_ID/sections_metadata?sort=title
# List data with filter
curl -H "$AUTH" $BASE_URL/data/$SPACE_ID/sections_metadata?filter.title=Ettan
# List data with text search
curl -H "$AUTH" $BASE_URL/data/$SPACE_ID/sections_metadata?q=Ettan
# List data and fetch relationships
curl -H "$AUTH" $BASE_URL/data/$SPACE_ID/sections_metadata?relationships=section
# List published data using apiKey
curl "$BASE_URL/data/$SPACE_ID/sections_metadata?apiKey=$API_KEY&published=1"
# Publish a document
export ID=$(curl -H "$AUTH" $BASE_URL/data/$SPACE_ID/sections_metadata | jq --raw-output .data[0].id)
curl -X PUT -H "$AUTH" -H "Content-Type: application/json" $BASE_URL/data/$SPACE_ID/sections_metadata/$ID -d '{"publishedVersion": 1}'
# The published document now appears in the listing (i.e. it's visible to clients)
curl "$BASE_URL/data/$SPACE_ID/sections_metadata?apiKey=$API_KEY&published=1"
# Updating a published document creates a draft version
curl -X PUT -H "$AUTH" -H "Content-Type: application/json" $BASE_URL/data/$SPACE_ID/sections_metadata/$ID -d '{"title": "New Title"}'
# View version history of document
curl -H "$AUTH" $BASE_URL/data/$SPACE_ID/sections_metadata/$ID?versions=1
# Publish the draft version
curl -X PUT -H "$AUTH" -H "Content-Type: application/json" $BASE_URL/data/$SPACE_ID/sections_metadata/$ID -d '{"publishedVersion": 2}'
# Unpublish document
curl -X PUT -H "$AUTH" -H "Content-Type: application/json" $BASE_URL/data/$SPACE_ID/sections_metadata/$ID -d '{"publishedVersion": null}'
mongo versioned2_development
show collections
# List models in space
db.models.find({spaceId: '5e9eb9b0161d73a8d440edfd'}, {name: 1}).limit(50).sort({createdAt: -1}).pretty()
# Get all data about a single model
db.models.find({_id: '5e9eb9c8161d73a8d440ee03'}).pretty()
# Update a document with $set
db.users.update({_id: '$USER_ID'}, {$set: {superUser: true}})
# Unset a property with $unset
db.users.update({_id: '$USER_ID'}, {$unset: {defaultSpaceId: ''}})
# List spaces
db.spaces.find({}, {name: 1, accountId: 1, dbKey: 1}).pretty()
# Remove a data document (name of collection is m_<space.dbKey>_<model.coll>)
db.m_se366cb3a_tags_metadata.remove({_id: '5e95811a1f0c7e28d58393d0'})
Using Apex Up:
up
Using Heroku:
heroku apps:create my-awesome-cms
git push heroku master