1. Rocky Assad
  2. cloudspokes_rest_api_challenge

Overview

HTTPS SSH

Cloudspokes Challenge #2037

Build a Simple API with Node.js, Ruby or Java

http://www.cloudspokes.com/challenges/2037

Rocky Assad 1/29/2013

Class Structure

The following 4 classes are just examples of the structure used to generate the JSON needed.

class User
{
    String id;
    String gravatarUrl;
    String firstName;
    String lastName;
    String email;
    String zipCode;
    String companyCode;
    String googlePlus;
    String skype;
    String phone;
    String about;
    String linkedinUrl;
    String companyUrl;
    List<User> topMatches;
    List<Need> needs;
    List<Offering> offerings;
    List<Meeting> upcomingMeetings;
    List<Meeting> pastMeetings;
}

class Meeting
{
    DateTime dateTime;
    String rating;
    User with;
}

class Need
{
    String need;
}

class Offering
{
    String offering;
}

JSON Structure

This is the JSON generated from the above classes populated with example data

[
   {
      "id":12345,
      "gravatarUrl":"http://www.gravatar.com/avatar/c2e27e40520152cd957623c16dcd1db9",
      "firstName":"Example",
      "lastName":"User",
      "email":"user@example.com",
      "zipCode":null,
      "companyCode":"Company Name",
      "googlePlus":"GoolePlusName",
      "skype":"skype",
      "phone":"(555) 555-5555",
      "about":"About the user",
      "linkedinUrl":"http://www.linkedin/exampleProfile",
      "companyUrl":"http://www.clouspokes.com",
      "topMatches":[
         {
            "id":"",
            "gravatarUrl":"http://www.gravatar.com/avatar/638aa4db3e2b6a5231557c29877bcffe",
            "firstName":"Example",
            "lastName":"User0",
            "email":null,
            "zipCode":null,
            "companyCode":null,
            "googlePlus":"GoolePlusName",
            "skype":"skype",
            "phone":null,
            "about":"About the user",
            "linkedinUrl":null,
            "companyUrl":null,
            "topMatches":null,
            "needs":[
               {
                  "need":"Some Great Need 0"
               },
               {
                  "need":"Some Great Need 1"
               },
               {
                  "need":"Some Great Need 2"
               }
            ],
            "offerings":[
               {
                  "offering":"Some Great Offering 0"
               },
               {
                  "offering":"Some Great Offering 1"
               },
               {
                  "offering":"Some Great Offering 2"
               }
            ],
            "upcomingMeetings":null,
            "pastMeetings":null
         },
         {
            "id":"",
            "gravatarUrl":"http://www.gravatar.com/avatar/638aa4db3e2b6a5231557c29877bcffe",
            "firstName":"Example",
            "lastName":"User1",
            "email":null,
            "zipCode":null,
            "companyCode":null,
            "googlePlus":"GoolePlusName",
            "skype":"skype",
            "phone":null,
            "about":"About the user",
            "linkedinUrl":null,
            "companyUrl":null,
            "topMatches":null,
            "needs":[
               {
                  "need":"Some Great Need 0"
               },
               {
                  "need":"Some Great Need 1"
               },
               {
                  "need":"Some Great Need 2"
               }
            ],
            "offerings":[
               {
                  "offering":"Some Great Offering 0"
               },
               {
                  "offering":"Some Great Offering 1"
               },
               {
                  "offering":"Some Great Offering 2"
               }
            ],
            "upcomingMeetings":null,
            "pastMeetings":null
         },
         {
            "id":"",
            "gravatarUrl":"http://www.gravatar.com/avatar/638aa4db3e2b6a5231557c29877bcffe",
            "firstName":"Example",
            "lastName":"User2",
            "email":null,
            "zipCode":null,
            "companyCode":null,
            "googlePlus":"GoolePlusName",
            "skype":"skype",
            "phone":null,
            "about":"About the user",
            "linkedinUrl":null,
            "companyUrl":null,
            "topMatches":null,
            "needs":[
               {
                  "need":"Some Great Need 0"
               },
               {
                  "need":"Some Great Need 1"
               },
               {
                  "need":"Some Great Need 2"
               }
            ],
            "offerings":[
               {
                  "offering":"Some Great Offering 0"
               },
               {
                  "offering":"Some Great Offering 1"
               },
               {
                  "offering":"Some Great Offering 2"
               }
            ],
            "upcomingMeetings":null,
            "pastMeetings":null
         }
      ],
      "needs":[
         {
            "need":"Some Need"
         },
         {
            "need":"Some Need"
         },
         {
            "need":"Some Need"
         }
      ],
      "offerings":[
         {
            "offering":"Some Offering"
         },
         {
            "offering":"Some Offering"
         },
         {
            "offering":"Some Offering"
         }
      ],
      "upcomingMeetings":[
         {
            "dateTime":"\/Date(1359430525780)\/",
            "rating":"3",
            "with":{
               "id":null
               "firstName":"Example",
               "lastName":"Client",
               "email":null,
               "zipCode":null,
               "companyCode":null,
               "googlePlus":null,
               "skype":null,
               "phone":null,
               "about":null,
               "linkedinUrl":null,
               "companyUrl":null,
               "topMatches":null,
               "needs":null,
               "offerings":null,
               "upcomingMeetings":null,
               "pastMeetings":null
            }
         },
         {
            "dateTime":"\/Date(1359437725780)\/",
            "rating":"4",
            "with":{
               "id":null,
               "firstName":"Example",
               "lastName":"Client",
               "email":null,
               "zipCode":null,
               "companyCode":null,
               "googlePlus":null,
               "skype":null,
               "phone":null,
               "about":null,
               "linkedinUrl":null,
               "companyUrl":null,
               "topMatches":null,
               "needs":null,
               "offerings":null,
               "upcomingMeetings":null,
               "pastMeetings":null
            }
         },
         {
            "dateTime":"\/Date(1359444925780)\/",
            "rating":"5",
            "with":{
               "id":null,
               "firstName":"Example",
               "lastName":"Client",
               "email":null,
               "zipCode":null,
               "companyCode":null,
               "googlePlus":null,
               "skype":null,
               "phone":null,
               "about":null,
               "linkedinUrl":null,
               "companyUrl":null,
               "topMatches":null,
               "needs":null,
               "offerings":null,
               "upcomingMeetings":null,
               "pastMeetings":null
            }
         }
      ],
      "pastMeetings":[
         {
            "dateTime":"\/Date(1359423325780)\/",
            "rating":"0",
            "with":{
               "id":null,
               "firstName":"Example",
               "lastName":"CEO",
               "email":null,
               "zipCode":null,
               "companyCode":null,
               "googlePlus":null,
               "skype":null,
               "phone":null,
               "about":null,
               "linkedinUrl":null,
               "companyUrl":null,
               "topMatches":null,
               "needs":null,
               "offerings":null,
               "upcomingMeetings":null,
               "pastMeetings":null
            }
         },
         {
            "dateTime":"\/Date(1359426925780)\/",
            "rating":"1",
            "with":{
               "id":null,
               "firstName":"Example",
               "lastName":"CEO",
               "email":null,
               "zipCode":null,
               "companyCode":null,
               "googlePlus":null,
               "skype":null,
               "phone":null,
               "about":null,
               "linkedinUrl":null,
               "companyUrl":null,
               "topMatches":null,
               "needs":null,
               "offerings":null,
               "upcomingMeetings":null,
               "pastMeetings":null
            }
         },
         {
            "dateTime":"\/Date(1359430525780)\/",
            "rating":"2",
            "with":{
               "id":null,
               "firstName":"Example",
               "lastName":"CEO",
               "email":null,
               "zipCode":null,
               "companyCode":null,
               "googlePlus":null,
               "skype":null,
               "phone":null,
               "about":null,
               "linkedinUrl":null,
               "companyUrl":null,
               "topMatches":null,
               "needs":null,
               "offerings":null,
               "upcomingMeetings":null,
               "pastMeetings":null
            }
         }
      ]
   }
]

Heroku Configuration

Application URL http://murmuring-thicket-2146.herokuapp.com

{
    "name": "cloudspoke-rest-user-api",
    "description": "Cloudspokes REST API User Application",
    "version": "0.0.1",
    "private": true,
    "dependencies": {
        "express": "3.x"
    },
    "engines": {
        "node": "0.8.x",
        "npm": "1.1.x",
    }
}

Note* I originally created this using mongodb to demonstrate REST API use with persistent data but replaced the wire data with static json data since it's going to be a future Cloudspokes challenge.

Testing REST API

When database support is implemented in a future challenge, replace <_id> with the record id.

Get all users

curl -i -X GET http://murmuring-thicket-2146.herokuapp.com/users

Get user with _id value of <_id>

curl -i -X GET http://murmuring-thicket-2146.herokuapp.com/users/<_id>

Delete user with _id value of some <_id>

curl -i -X DELETE http://murmuring-thicket-2146.herokuapp.com/users/<_id>

Add a new user (example with inline JSON below)

curl -i -X POST -H 'Content-Type: application/json' -d '<raw_json>' http://murmuring-thicket-2146.herokuapp.com/users

Modify user with _id value of <_id> (example with inline JSON below)

curl -i -X PUT -H 'Content-Type: application/json' -d '<raw_json>' http://murmuring-thicket-2146.herokuapp.com/users/<_id>

Modify user from inline JSON (with JSON populated)

curl -i -X PUT -H 'Content-Type: application/json' -d '{"id":null,"gravatarUrl":"http://www.gravatar.com/avatar/c2e27e40520152cd957623c16dcd1db9","firstName":"Example","lastName":"Assad","email":"user@example.com","zipCode":null,"companyCode":"Company Name","googlePlus":"GoolePlusName","skype":"skype","phone":"(555) 555-5555","about":"About the user","linkedinUrl":"http://www.linkedin/exampleProfile","companyUrl":"http://www.clouspokes.com","topMatches":[{"id":"","gravatarUrl":null,"firstName":"Example","lastName":"User0","email":null,"zipCode":null,"companyCode":null,"googlePlus":"GoolePlusName","skype":"skype","phone":null,"about":"About the user","linkedinUrl":null,"companyUrl":null,"topMatches":null,"needs":[{"need":"Some Great Need 0"},{"need":"Some Great Need 1"},{"need":"Some Great Need 2"}],"offerings":[{"offering":"Some Great Offering 0"},{"offering":"Some Great Offering 1"},{"offering":"Some Great Offering 2"}],"upcomingMeetings":null,"pastMeetings":null},{"id":"","gravatarUrl":null,"firstName":"Example","lastName":"User1","email":null,"zipCode":null,"companyCode":null,"googlePlus":"GoolePlusName","skype":"skype","phone":null,"about":"About the user","linkedinUrl":null,"companyUrl":null,"topMatches":null,"needs":[{"need":"Some Great Need 0"},{"need":"Some Great Need 1"},{"need":"Some Great Need 2"}],"offerings":[{"offering":"Some Great Offering 0"},{"offering":"Some Great Offering 1"},{"offering":"Some Great Offering 2"}],"upcomingMeetings":null,"pastMeetings":null},{"id":"","gravatarUrl":null,"firstName":"Example","lastName":"User2","email":null,"zipCode":null,"companyCode":null,"googlePlus":"GoolePlusName","skype":"skype","phone":null,"about":"About the user","linkedinUrl":null,"companyUrl":null,"topMatches":null,"needs":[{"need":"Some Great Need 0"},{"need":"Some Great Need 1"},{"need":"Some Great Need 2"}],"offerings":[{"offering":"Some Great Offering 0"},{"offering":"Some Great Offering 1"},{"offering":"Some Great Offering 2"}],"upcomingMeetings":null,"pastMeetings":null}],"needs":[{"need":"Some Need"},{"need":"Some Need"},{"need":"Some Need"}],"offerings":[{"offering":"Some Offering"},{"offering":"Some Offering"},{"offering":"Some Offering"}],"upcomingMeetings":[{"dateTime":"\/Date(1359486201832)\/","rating":"3","with":{"id":null,"gravatarUrl":null,"firstName":"Example","lastName":"Client","email":null,"zipCode":null,"companyCode":null,"googlePlus":null,"skype":null,"phone":null,"about":null,"linkedinUrl":null,"companyUrl":null,"topMatches":null,"needs":null,"offerings":null,"upcomingMeetings":null,"pastMeetings":null}},{"dateTime":"\/Date(1359493401832)\/","rating":"4","with":{"id":null,"gravatarUrl":null,"firstName":"Example","lastName":"Client","email":null,"zipCode":null,"companyCode":null,"googlePlus":null,"skype":null,"phone":null,"about":null,"linkedinUrl":null,"companyUrl":null,"topMatches":null,"needs":null,"offerings":null,"upcomingMeetings":null,"pastMeetings":null}},{"dateTime":"\/Date(1359500601832)\/","rating":"5","with":{"id":null,"gravatarUrl":null,"firstName":"Example","lastName":"Client","email":null,"zipCode":null,"companyCode":null,"googlePlus":null,"skype":null,"phone":null,"about":null,"linkedinUrl":null,"companyUrl":null,"topMatches":null,"needs":null,"offerings":null,"upcomingMeetings":null,"pastMeetings":null}}],"pastMeetings":[{"dateTime":"\/Date(1359479001832)\/","rating":"0","with":{"id":null,"gravatarUrl":"http://www.gravatar.com/avatar/c2e27e40520152cd957623c16dcd1db9","firstName":"Example","lastName":"CEO","email":null,"zipCode":null,"companyCode":null,"googlePlus":null,"skype":null,"phone":null,"about":null,"linkedinUrl":null,"companyUrl":null,"topMatches":null,"needs":null,"offerings":null,"upcomingMeetings":null,"pastMeetings":null}},{"dateTime":"\/Date(1359482601832)\/","rating":"1","with":{"id":null,"gravatarUrl":"http://www.gravatar.com/avatar/c2e27e40520152cd957623c16dcd1db9","firstName":"Example","lastName":"CEO","email":null,"zipCode":null,"companyCode":null,"googlePlus":null,"skype":null,"phone":null,"about":null,"linkedinUrl":null,"companyUrl":null,"topMatches":null,"needs":null,"offerings":null,"upcomingMeetings":null,"pastMeetings":null}},{"dateTime":"\/Date(1359486201832)\/","rating":"2","with":{"id":null,"gravatarUrl":"http://www.gravatar.com/avatar/c2e27e40520152cd957623c16dcd1db9","firstName":"Example","lastName":"CEO","email":null,"zipCode":null,"companyCode":null,"googlePlus":null,"skype":null,"phone":null,"about":null,"linkedinUrl":null,"companyUrl":null,"topMatches":null,"needs":null,"offerings":null,"upcomingMeetings":null,"pastMeetings":null}}]}' http://murmuring-thicket-2146.herokuapp.com/users/12345

Add new user from inline JSON (with JSON populated)

curl -i -X POST -H 'Content-Type: application/json' -d '{"id":null,"gravatarUrl":"http://www.gravatar.com/avatar/c2e27e40520152cd957623c16dcd1db9","firstName":"Example","lastName":"Assad","email":"user@example.com","zipCode":null,"companyCode":"Company Name","googlePlus":"GoolePlusName","skype":"skype","phone":"(555) 555-5555","about":"About the user","linkedinUrl":"http://www.linkedin/exampleProfile","companyUrl":"http://www.clouspokes.com","topMatches":[{"id":"","gravatarUrl":null,"firstName":"Example","lastName":"User0","email":null,"zipCode":null,"companyCode":null,"googlePlus":"GoolePlusName","skype":"skype","phone":null,"about":"About the user","linkedinUrl":null,"companyUrl":null,"topMatches":null,"needs":[{"need":"Some Great Need 0"},{"need":"Some Great Need 1"},{"need":"Some Great Need 2"}],"offerings":[{"offering":"Some Great Offering 0"},{"offering":"Some Great Offering 1"},{"offering":"Some Great Offering 2"}],"upcomingMeetings":null,"pastMeetings":null},{"id":"","gravatarUrl":null,"firstName":"Example","lastName":"User1","email":null,"zipCode":null,"companyCode":null,"googlePlus":"GoolePlusName","skype":"skype","phone":null,"about":"About the user","linkedinUrl":null,"companyUrl":null,"topMatches":null,"needs":[{"need":"Some Great Need 0"},{"need":"Some Great Need 1"},{"need":"Some Great Need 2"}],"offerings":[{"offering":"Some Great Offering 0"},{"offering":"Some Great Offering 1"},{"offering":"Some Great Offering 2"}],"upcomingMeetings":null,"pastMeetings":null},{"id":"","gravatarUrl":null,"firstName":"Example","lastName":"User2","email":null,"zipCode":null,"companyCode":null,"googlePlus":"GoolePlusName","skype":"skype","phone":null,"about":"About the user","linkedinUrl":null,"companyUrl":null,"topMatches":null,"needs":[{"need":"Some Great Need 0"},{"need":"Some Great Need 1"},{"need":"Some Great Need 2"}],"offerings":[{"offering":"Some Great Offering 0"},{"offering":"Some Great Offering 1"},{"offering":"Some Great Offering 2"}],"upcomingMeetings":null,"pastMeetings":null}],"needs":[{"need":"Some Need"},{"need":"Some Need"},{"need":"Some Need"}],"offerings":[{"offering":"Some Offering"},{"offering":"Some Offering"},{"offering":"Some Offering"}],"upcomingMeetings":[{"dateTime":"\/Date(1359486201832)\/","rating":"3","with":{"id":null,"gravatarUrl":null,"firstName":"Example","lastName":"Client","email":null,"zipCode":null,"companyCode":null,"googlePlus":null,"skype":null,"phone":null,"about":null,"linkedinUrl":null,"companyUrl":null,"topMatches":null,"needs":null,"offerings":null,"upcomingMeetings":null,"pastMeetings":null}},{"dateTime":"\/Date(1359493401832)\/","rating":"4","with":{"id":null,"gravatarUrl":null,"firstName":"Example","lastName":"Client","email":null,"zipCode":null,"companyCode":null,"googlePlus":null,"skype":null,"phone":null,"about":null,"linkedinUrl":null,"companyUrl":null,"topMatches":null,"needs":null,"offerings":null,"upcomingMeetings":null,"pastMeetings":null}},{"dateTime":"\/Date(1359500601832)\/","rating":"5","with":{"id":null,"gravatarUrl":null,"firstName":"Example","lastName":"Client","email":null,"zipCode":null,"companyCode":null,"googlePlus":null,"skype":null,"phone":null,"about":null,"linkedinUrl":null,"companyUrl":null,"topMatches":null,"needs":null,"offerings":null,"upcomingMeetings":null,"pastMeetings":null}}],"pastMeetings":[{"dateTime":"\/Date(1359479001832)\/","rating":"0","with":{"id":null,"gravatarUrl":"http://www.gravatar.com/avatar/c2e27e40520152cd957623c16dcd1db9","firstName":"Example","lastName":"CEO","email":null,"zipCode":null,"companyCode":null,"googlePlus":null,"skype":null,"phone":null,"about":null,"linkedinUrl":null,"companyUrl":null,"topMatches":null,"needs":null,"offerings":null,"upcomingMeetings":null,"pastMeetings":null}},{"dateTime":"\/Date(1359482601832)\/","rating":"1","with":{"id":null,"gravatarUrl":"http://www.gravatar.com/avatar/c2e27e40520152cd957623c16dcd1db9","firstName":"Example","lastName":"CEO","email":null,"zipCode":null,"companyCode":null,"googlePlus":null,"skype":null,"phone":null,"about":null,"linkedinUrl":null,"companyUrl":null,"topMatches":null,"needs":null,"offerings":null,"upcomingMeetings":null,"pastMeetings":null}},{"dateTime":"\/Date(1359486201832)\/","rating":"2","with":{"id":null,"gravatarUrl":"http://www.gravatar.com/avatar/c2e27e40520152cd957623c16dcd1db9","firstName":"Example","lastName":"CEO","email":null,"zipCode":null,"companyCode":null,"googlePlus":null,"skype":null,"phone":null,"about":null,"linkedinUrl":null,"companyUrl":null,"topMatches":null,"needs":null,"offerings":null,"upcomingMeetings":null,"pastMeetings":null}}]}' http://murmuring-thicket-2146.herokuapp.com/users