Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
34 commits
Select commit Hold shift + click to select a range
a871be3
scaffold files
jonathanheemstra Dec 15, 2016
924d942
Merge pull request #1 from jonathanheemstra/scaffold-files
jonathanheemstra Dec 15, 2016
1aa757a
set up server
jonathanheemstra Dec 15, 2016
7044cdd
Merge pull request #2 from jonathanheemstra/setup-server
jonathanheemstra Dec 15, 2016
43b1046
set up parse json file
jonathanheemstra Dec 15, 2016
f9874ae
Merge pull request #3 from jonathanheemstra/set-up-parse-json
jonathanheemstra Dec 15, 2016
d5d1bee
set up parse url
jonathanheemstra Dec 15, 2016
b464563
Merge pull request #4 from jonathanheemstra/set-up-parse-url
jonathanheemstra Dec 15, 2016
7e91750
set up ski data model
jonathanheemstra Dec 15, 2016
e96f41d
Merge pull request #5 from jonathanheemstra/build-ski-data-model
jonathanheemstra Dec 15, 2016
bf9d107
build router for app
jonathanheemstra Dec 15, 2016
e689008
Merge pull request #6 from jonathanheemstra/build-router
jonathanheemstra Dec 15, 2016
c555b7b
set up routes on server file
jonathanheemstra Dec 15, 2016
bfe13b2
Merge pull request #7 from jonathanheemstra/add-routes-to-server
jonathanheemstra Dec 15, 2016
0ded489
set up data storage
jonathanheemstra Dec 15, 2016
72f4f96
Merge pull request #8 from jonathanheemstra/add-storage
jonathanheemstra Dec 15, 2016
d507344
add routes to server.js
jonathanheemstra Dec 15, 2016
13fd13d
Merge pull request #9 from jonathanheemstra/add-routes-to-server
jonathanheemstra Dec 15, 2016
4036444
set up delete route
jonathanheemstra Dec 15, 2016
4bb2e6b
Merge pull request #10 from jonathanheemstra/set-delete-route
jonathanheemstra Dec 15, 2016
e77e640
add testing
jonathanheemstra Dec 15, 2016
18d336e
Merge pull request #11 from jonathanheemstra/setup-tests
jonathanheemstra Dec 15, 2016
6a0b254
set up tests
jonathanheemstra Dec 15, 2016
32f9e9d
Merge pull request #12 from jonathanheemstra/setup-tests
jonathanheemstra Dec 15, 2016
6c5738b
fix tests
jonathanheemstra Dec 15, 2016
48663fc
scaffold files for lab 9
jonathanheemstra Dec 16, 2016
cbb0cb3
Merge pull request #13 from jonathanheemstra/lab-9-scaffold
jonathanheemstra Dec 16, 2016
0d02d42
set up routes file
jonathanheemstra Dec 16, 2016
306dd24
Merge pull request #14 from jonathanheemstra/lab-9-routes-file
jonathanheemstra Dec 16, 2016
b3045ef
add response file
jonathanheemstra Dec 16, 2016
0e7c243
Merge pull request #15 from jonathanheemstra/lab-9-response-file
jonathanheemstra Dec 16, 2016
77ff834
successfully refactored
jonathanheemstra Dec 16, 2016
7cbff44
Merge pull request #16 from jonathanheemstra/lab-9-persistent-storage
jonathanheemstra Dec 16, 2016
3a6aa70
readme updated
jonathanheemstra Dec 16, 2016
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 21 additions & 0 deletions .eslintrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
{
"rules": {
"no-console": "off",
"indent": [ "error", 2 ],
"quotes": [ "error", "single" ],
"semi": ["error", "always"],
"linebreak-style": [ "error", "unix" ]
},
"env": {
"es6": true,
"node": true,
"mocha": true,
"jasmine": true
},
"ecmaFeatures": {
"modules": true,
"experimentalObjectRestSpread": true,
"impliedStrict": true
},
"extends": "eslint:recommended"
}
120 changes: 120 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,120 @@

# Created by https://www.gitignore.io/api/node,macos,windows,linux

### Node ###
# Logs
logs
*.log
npm-debug.log*
node_modules
coverage

# Runtime data
pids
*.pid
*.seed
*.pid.lock

# Directory for instrumented libs generated by jscoverage/JSCover
lib-cov

# Coverage directory used by tools like istanbul
coverage

# nyc test coverage
.nyc_output

# Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files)
.grunt

# node-waf configuration
.lock-wscript

# Compiled binary addons (http://nodejs.org/api/addons.html)
build/Release

# Dependency directories
node_modules
jspm_packages

# Optional npm cache directory
.npm

# Optional eslint cache
.eslintcache

# Optional REPL history
.node_repl_history

# Output of 'npm pack'
*.tgz

# Yarn Integrity file
.yarn-integrity



### macOS ###
*.DS_Store
.AppleDouble
.LSOverride

# Icon must end with two \r
Icon
# Thumbnails
._*
# Files that might appear in the root of a volume
.DocumentRevisions-V100
.fseventsd
.Spotlight-V100
.TemporaryItems
.Trashes
.VolumeIcon.icns
.com.apple.timemachine.donotpresent
# Directories potentially created on remote AFP share
.AppleDB
.AppleDesktop
Network Trash Folder
Temporary Items
.apdisk


### Windows ###
# Windows image file caches
Thumbs.db
ehthumbs.db

# Folder config file
Desktop.ini

# Recycle Bin used on file shares
$RECYCLE.BIN/

# Windows Installer files
*.cab
*.msi
*.msm
*.msp

# Windows shortcuts
*.lnk


### Linux ###
*~


### Extra ignore ###
.console.js

# temporary files which can be created if a process still has a handle open of a deleted file
.fuse_hidden*

# KDE directory preferences
.directory

# Linux trash folder which might appear on any partition or disk
.Trash-*

# .nfs files are created when an open file is removed but is still being accessed
.nfs*
29 changes: 29 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
# Vanilla Ski Report REST api

## About
The vanilla Ski Report REST api is built to allow consumers to get valuable ski report data about any area they want to ski in. The api will respond to any of the following commands `GET`, `POST`, `DELETE`. The routes on the api are currently set to be reachable at `localhost:<YOUR PORT NUMBER>/api/ski-data`. In order for this API to work you will need to `npm i` to install `node-uuid` and `bluebird`, which is required to run this API. You will also need HTTPie installed globally on your machine in order for the API responses to reach your terminal correctly.

## Current Version (0.1.0)
* The current version of this application will persist user data locally on the users file system. Users can `POST`, `GET`, and `DELETE` files.

## Setting up Vanilla Ski Report REST api on your local machine
* Fork this repo
* `git clone` the forked copy to your local machine
* Node is required to run the server. Confirm you have `node` installed on your local machine by typing `npm -v` into your terminal. If you don't have node installed please follow the instructions [here](https://nodejs.org/en/).
* Install the dependencies of `node-uuid` and `bluebird` by running `npm i`.
* In order to turn on the server you will need to run either `nodemon server.js` or `node server.js` if you do not have nodemon installed globally.
* When you start the server via `node server.js` the port number should be printed to the terminal console. You will need to provide this to any users wanting to connect.

## API Commands
* `POST`: `http POST localhost:<YOUR PORT NUMBER>/api/ski-data location='<YOUR LOCATION DATA>' rating=<NUMBER>`
* This will return a header with status code and a JSON representation of the data you just added.
* The `POST` will write a file to the `../data/location/` file saved with `uuid` as the file name.
* `GET`: `http localhost:<YOUR PORT NUMBER>/api/ski-data?id=<ID OF OBJECT YOU WANT BACK>`
* This will return a header with status code and a JSON representation of the data you just requested.
* If you request a file via and `id` that does not exist then the api will return 404.
* If you run a bad `GET` method and do not pass an `id` the api will return 400.
* `DELETE`: `http DELETE localhost:<YOUR PORT NUMBER>/api/ski-data?id=<ID OF OBJECT YOU WANT TO DELETE>`
* This will return a header with a status code of 204.
* The object deleted will be removed for the database.
* `Mocha`: this will run tests set up to validate that the code is working as expected.
* at the time of publication of this README.md all tests are currently passing.
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good job with the README!

1 change: 1 addition & 0 deletions data/location/82007ecc-4bf0-4207-8b59-f6b1c09b06a0.json
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{"id":"82007ecc-4bf0-4207-8b59-f6b1c09b06a0","location":"Mt baker","rating":10}
1 change: 1 addition & 0 deletions data/location/8b6a4e5c-0bc0-4d57-978d-9fa88fb67e4c.json
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{"id":"8b6a4e5c-0bc0-4d57-978d-9fa88fb67e4c","location":"mt baker","rating":"5"}
23 changes: 23 additions & 0 deletions gulpfile.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
'use strict';

const gulp = require('gulp');
const eslint = require('gulp-eslint');
const mocha = require('mocha');

gulp.task('lint', function() {
gulp.src(['**/*.js', '!node_modules'])
.pipe(eslint())
.pipe(eslint.format())
.pipe(eslint.failAfterError());
});

gulp.task('test', function() {
gulp.src(['./test/*test.js','!node_modules'], {read:false})
.pipe(mocha({report: 'spec'}));
});

gulp.task('dev', function() {
gulp.watch(['**/*.js', '!node_modules'], ['lint', 'test']);
});

gulp.task('default', ['dev']);
10 changes: 5 additions & 5 deletions lab-08_in_memory_resource_api.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,11 @@
* `README.md`

## Description
* Create the following directories to organize your code:
* `lib`
* `model`
* `test`
* Create an HTTP server using the native NodeJS `http` module
* [x] Create the following directories to organize your code:
* [x] `lib`
* [x] `model`
* [x] `test`
* [x] Create an HTTP server using the native NodeJS `http` module
* Create an object constructor that creates a _simple resource_ with at least 3 properties
* include an `id` property that is set to a unique id (**hint:** you'll need to use `node-uuid`)
* include two additional properties of your choice (ex: name, content, etc.)
Expand Down
36 changes: 36 additions & 0 deletions lib/data.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
'use strict';

const Promise = require('bluebird');
const fs = Promise.promisifyAll(require('fs'), {suffix: 'Prom'});

module.exports = exports = {};

exports.setData = (schemaName, item) => {
if(!schemaName) return Promise.reject(new Error('Expected schema name but was not provided one'));
if(!item) return Promise.reject(new Error('Expected item but was not provided one'));

let json = JSON.stringify(item);
return fs.writeFileProm(`${__dirname}/../data/${schemaName}/${item.id}.json`, json)
.then( () => item)
.catch( err => Promise.reject(err));
};

exports.getData = (schemaName, id) => {
if(!schemaName) return Promise.reject(new Error('Expected schema name but was not provided one'));
if(!id) return Promise.reject(new Error('Expected id but was not provided one'));

return fs.readFileProm(`${__dirname}/../data/${schemaName}/${id}.json`)
.then( data => {
let item = JSON.parse(data.toString());
return item;
})
.catch( err => Promise.reject(err));
};

exports.removeData = (schemaName, id) => {
if(!schemaName) return Promise.reject(new Error('Expected schema name but was not provided one'));
if(!id) return Promise.reject(new Error('Expected id but was not provided one'));

return fs.unlinkProm(`${__dirname}/../data/${schemaName}/${id}.json`)
.catch( err => Promise.reject(err));
};
32 changes: 32 additions & 0 deletions lib/parse-json.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
'use strict';

module.exports = function(req) {
return new Promise( (resolve, reject) => {
if(req.method === 'POST' || req.method === 'PUT') {
var body = '';

req.on('data', data => {
body += data.toString();
});

req.on('end', () => {
try {
req.body = JSON.parse(body);
resolve(req);
} catch(err) {
console.error(err);
reject(err);
}
});

req.on('error', err => {
console.error(err);
reject(err);
});

return;
}

resolve();
});
};
10 changes: 10 additions & 0 deletions lib/parse-url.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
'use strict';

const parseURL = require('url').parse;
const parseQuery = require('querystring').parse;

module.exports = function(req) {
req.url = parseURL(req.url);
req.url.query = parseQuery(req.url.query);
return Promise.resolve(req);
};
15 changes: 15 additions & 0 deletions lib/response.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
'use strict';

module.exports = exports = {};

exports.JSON = function(res, status, data) {
res.writeHead(status, {'Content-Type': 'application/json'});
res.write(JSON.stringify(data));
res.end();
};

exports.text = function(res, status, msg) {
res.writeHead(status, {'Content-Type': 'text/plain'});
res.write(msg);
res.end();
};
51 changes: 51 additions & 0 deletions lib/router.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
'use strict';

const parseURL = require('./parse-url.js');
const parseJSON = require('./parse-json.js');
const response = require('../lib/response.js');

const Router = module.exports = function() {
this.routes = {
GET: {},
POST: {},
PUT: {},
DELETE: {}
};
};

Router.prototype.get = function(endpoint, callback) {
this.routes.GET[endpoint] = callback;
};

Router.prototype.post = function(endpoint, callback) {
this.routes.POST[endpoint] = callback;
};

Router.prototype.put = function(endpoint, callback) {
this.routes.PUT[endpoint] = callback;
};

Router.prototype.delete = function(endpoint, callback) {
this.routes.DELETE[endpoint] = callback;
};

Router.prototype.route = function() {
return (req, res) => {
Promise.all([
parseURL(req),
parseJSON(req)
])
.then( () => {
if(typeof this.routes[req.method][req.url.pathname] === 'function') {
this.routes[req.method][req.url.pathname](req, res);
return;
}
console.error('route not found');
response.text(res, 404, 'Not found');
})
.catch( err => {
console.error(err);
response.text(res, 400, 'Bad request');
});
};
};
12 changes: 12 additions & 0 deletions model/ski-data.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
'use strict';

const uuid = require('node-uuid');

module.exports = function(location, rating) {
if(!location) throw new Error('expected location');
if(!rating) throw new Error('expected rating');

this.id = uuid.v4();
this.location = location;
this.rating = rating;
};
Loading