Geocaching API Demo

Today, we're going to make an example API that involves geocaching. Basically, we are going to make a fake Geocache generator that would ease the development of a geocaching website with fake data. This tutorial will go through the entire process of creating an API from beginning to end. If you have any questions or feedback, please leave a comment below. Let's get started! :)

Test out the final result of this demo API


First, let's create a new API. To do this, click on "New API" from the side navbar, give your API a name, and then click "Add new API". This'll take you to the API editor.

The API editor is split into two parts: a code editor on the left and a live preview on the right. The live preview will automatically execute your API code and show the results of your API code whenever it detects a change. You can also click Test API if you want to manually generate a new result.

After looking at some geocaching websites, it looks like these are some of the most common properties that a geocaching website would need.

  • Name of the spot
  • Creator's username
  • Rating
  • Favorites
  • Number of visits
  • Difficulty
  • Terrain
  • Size
  • Date created
  • Date updated
  • Coordinates

For the Geocache name, we are going to generate a very basic name consisting of adjectives and nouns.

api.name = trailname();

function trailname() {  
    let trails     = ["trail", "path", "route", "stream", "walkway", "beaten path", "footpath"]
    let adjectives = ["dusty", "old", "scenic", "historic", "shady", "sunny"];
    let colors     = ["red", "orange", "yellow", "green", "blue", "indigo", "violet"];

    let combos = [
        [colors, trails],
        [adjectives, trails],
        [colors, adjectives, trails]
    ];

    let trailname = "";
    list(combos).forEach(part => trailname += " " + capitalize(list(part)));
    return trailname.trim();

    function capitalize(str) {
        return str.charAt(0).toUpperCase() + str.slice(1);
    }
}
{
  "name": "Violet Dusty Trail"
}

So now we have a name, but that trail function generator is kind of long and looks messy in our API. We are going to move the trailname function to a snippet since we may use it later on in other APIs and it'll clean up our code a bit. You can read more about implementing snippets here.

Here's what our API looks like now with our new trailname snippet.

const trailname = require('~trailname');  
api.name        = trailname();  

Next, we are going to generate the geocache creator's username. We are to use the Faker.js global snippet for this field as well as for generating the coordinates for our geocache.

...
const faker     = require('faker'); // Faker.js library  
api.username    = faker.internet.userName();  
...
{
  "username": "Dewayne75"
}

Let's knock a few more properties out of the way with the random.numeric and list function. Rating, favorites, number of visits, difficulty, and terrain will all take numeric values for star ratings and pure numbers for favorites and number of visits. We will also try and make the values more realistic by basing values like favorites and visits off of previously calculated values.

...
api.rating     = random.numeric(0, 50) / 10;  
api.favorites  = Math.ceil(api.rating * random.numeric(1, 15));  
api.visits     = api.favorites * random.numeric(1, 15)  
api.difficulty = random.numeric(1, 5);  
api.terrain    = random.numeric(1, 5);  
api.size       = list(['mini', 'small', 'medium', 'big', 'large']);  
...
{
  "rating": 2.9,
  "favorites": 41,
  "visits": 369,
  "difficulty": 2,
  "terrain": 4,
  "size": "large"
}

For date created and date updated, we'll take advantage of the moment library to provide readable formatting.

...
const moment = require('moment');

// Created 30 - 900 days ago
let created = timestamp() - 86400 * random.numeric(30, 900);

// Moment accepts timestamps in milliseconds
api.created = moment(created * 1000).format('LL');

// Updated date will be before the present but after the creation date
let updated = timestamp() - random.numeric(0, timestamp() - created);  
api.updated = moment(updated * 1000).format('LL');  
...
{
  "created": "July 25, 2015",
  "updated": "March 26, 2016"
}

And finally, let's use the Faker.js library again to generate a random set of coordinates for the geocache.

api.coords = `${faker.address.latitude()} ${faker.address.longitude()}`;  
{
    "coords": "40.7013 15.9303"
}

And we are finished! Here is the final API code (without the snippet so you can copy and paste directly) and an example of the results that it generated.

Call the API directly yourself

const faker  = require('faker'); // Faker.js library  
const moment = require('moment');

api.name       = trailname();  
api.username   = faker.internet.userName();  
api.rating     = random.numeric(0, 50) / 10;  
api.favorites  = Math.ceil(api.rating * random.numeric(1, 15));  
api.visits     = api.favorites * random.numeric(1, 15)  
api.difficulty = random.numeric(1, 5);  
api.terrain    = random.numeric(1, 5);  
api.size       = list(['mini', 'small', 'medium', 'big', 'large']);

// Created 30 - 900 days ago
let created = timestamp() - 86400 * random.numeric(30, 900);

// Moment accepts timestamps in milliseconds
api.created = moment(created * 1000).format('LL');

// Updated date will be before the present but after the creation date
let updated = timestamp() - random.numeric(0, timestamp() - created);  
api.updated = moment(updated * 1000).format('LL');

api.coords = `${faker.address.latitude()} ${faker.address.longitude()}`;

// Snippet code
function trailname() {  
    let trails     = ["trail", "path", "route", "stream", "walkway", "beaten path", "footpath"]
    let adjectives = ["dusty", "old", "scenic", "historic", "shady", "sunny"];
    let colors     = ["red", "orange", "yellow", "green", "blue", "indigo", "violet"];

    let combos = [
        [colors, trails],
        [adjectives, trails],
        [colors, adjectives, trails]
    ];

    let trailName = "";
    list(combos).forEach(part => trailName += " " + capitalize(list(part)));

    return trailName.trim();

    function capitalize(str) {
        return str.charAt(0).toUpperCase() + str.slice(1);
    }
}
{
  "name": "Indigo Dusty Path",
  "username": "Henry_Schaden",
  "rating": 1.8,
  "favorites": 15,
  "visits": 45,
  "difficulty": 4,
  "terrain": 2,
  "size": "mini",
  "created": "September 11, 2015",
  "updated": "November 15, 2015",
  "coords": "38.3802 -23.2441"
}