Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

initial import #1

Merged
merged 18 commits into from
Sep 15, 2014
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
1 change: 1 addition & 0 deletions .dockerignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
node_modules
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -23,3 +23,6 @@ build/Release
# Deployed apps should consider commenting this line out:
# see https://npmjs.org/doc/faq.html#Should-I-check-my-node_modules-folder-into-git
node_modules

key.json
*~
10 changes: 10 additions & 0 deletions .travis.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
language: node_js
node_js:
- '0.10'
before_install:
- openssl aes-256-cbc -K $encrypted_8bfe06cf1581_key -iv $encrypted_8bfe06cf1581_iv
-in key.json.enc -out key.json -d
before_script:
- npm run-script lint
env:
- DATASET_ID=proppy-mvm-dogfood
20 changes: 20 additions & 0 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
# How to become a contributor and submit your own code

## Contributor License Agreements

We'd love to accept your patches! Before we can take them, we have to jump a couple of legal hurdles.

Please fill out either the individual or corporate Contributor License Agreement (CLA).

* If you are an individual writing original source code and you're sure you own the intellectual property, then you'll need to sign an [individual CLA](http://code.google.com/legal/individual-cla-v1.0.html).
* If you work for a company that wants to allow you to contribute your work, then you'll need to sign a [corporate CLA](http://code.google.com/legal/corporate-cla-v1.0.html).

Follow either of the two links above to access the appropriate CLA and instructions for how to sign and return it. Once we receive it, we'll be able to accept your pull requests.

## Contributing A Patch

1. Submit an issue describing your proposed change to the repo in question.
1. The repo owner will respond to your issue promptly.
1. If your proposed change is accepted, and you haven't already done so, sign a Contributor License Agreement (see details above).
1. Fork the desired repo, develop and test your code changes.
1. Submit a pull request.
1 change: 1 addition & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
FROM google/nodejs-runtime
21 changes: 21 additions & 0 deletions Gulpfile.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
var gulp = require('gulp');
var Dredd = require('dredd');
var app = require('./todos.js');

gulp.task('dredd', function(cb) {
var server = app.listen(8080, function() {
var dredd = new Dredd({
blueprintPath: 'todos.apib',
server: 'http://localhost:8080',
options: {
hookfiles: 'test_hooks.js'
}
});
dredd.run(function(error, stats){
server.close();
cb();
});
});
});

gulp.task('test', ['dredd']);
86 changes: 84 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,88 @@
gcloud-node-todos
=================

TodoMVC sample for gcloud-node
[![Build Status](https://travis-ci.org/GoogleCloudPlatform/gcloud-node-todos.svg?branch=master)](https://travis-ci.org/GoogleCloudPlatform/gcloud-node-todos)

See https://github.com/GoogleCloudPlatform/gcloud-node-todos/pull/1
TodoMVC backend using [gcloud-node](//github.com/GoogleCloudPlatform/gcloud-node).

# API

- Insert a todo

curl -X POST -d '{text: "do this"}' http://localhost:8080/todos

- Get a todo

curl -X GET http://localhost:8080/todos/{{todo id}}

- Mark a todo as done

curl -X PUT -d '{text: "do this", "done": true}' http://localhost:8080/todos/{{todo id}}

- Delete a todo

curl -X DELETE http://localhost:8080/todos/{{todo id}}

- Get all todos

curl -X GET http://localhost:8080/todos

- Clear all `done` todos

curl -X DELETE http://localhost:8080/todos

# Prerequisites

- Create a new cloud project on [console.developers.google.com](http://console.developers.google.com)
- [Enable](https://console.developers.google.com/flows/enableapi?apiid=datastore) the [Google Cloud Datastore API](https://developers.google.com/datastore)
- Create a new service account and copy the `JSON` credentials to `key.json`
- Export your project id

export PROJECT_ID=<project id>

# Run locally

# set your default dataset
export DATASET_ID=$PROJECT_ID
# fetch the dependencies
npm install
# start the app
npm start
# run acceptance test
dredd todos.apib http://localhost:8080 --hookfiles test_hooks.js

# Run in docker

# check that docker is running
boot2docker up
export DOCKER_HOST=$(boot2docker shellinit)

# build your docker image
docker build -t app .
# start a new docker container
docker run -e DATASET_ID=$PROJECT_ID -p 8080:8080 app

# test the app
curl -X GET http://$(boot2docker ip):8080

# Run w/ [Managed VMs](https://developers.google.com/appengine/docs/managed-vms/)

# get gcloud
curl https://sdk.cloud.google.com | bash
# authorize gcloud and set your default project
gcloud auth login
gcloud config set project $PROJECT_ID

# get managed vms component
gcloud components update app-engine-managed-vms

# check that docker is running
boot2docker up

# run the app locally
gcloud preview app run .
curl -X GET http://localhost:8080

# deploy the app to production
gcloud preview app deploy .
curl -X GET http://$PROJECT_ID.appspot.com
12 changes: 12 additions & 0 deletions app.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
application: gcloud-node-todos
module: default
version: 1
runtime: custom
api_version: 1
vm: true
manual_scaling:
instances: 1

handlers:
- url: .*
script: dynamic
Binary file added key.json.enc
Binary file not shown.
21 changes: 21 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
{
"name": "gcloud-node-todos",
"description": "todomvc sample for gcloud-node",
"version": "0.0.1",
"license": "Apache 2.0",
"dependencies": {
"express": "^4.5.1",
"body-parser": "^1.4.3",
"gcloud": "^0.6.0"
},
"devDependencies": {
"jshint": "^2.5.2",
"dredd": "^0.3.9",
"request": "^2.42.0",
"gulp": "^3.8.8"
},
"scripts": {
"lint": "jshint *.js",
"test": "gulp test"
}
}
1 change: 1 addition & 0 deletions server.js
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
require('./todos.js').listen(8080);
43 changes: 43 additions & 0 deletions test_hooks.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
var request = require('request');
// imports the hooks module _injected_ by dredd.
var hooks = require('hooks');
Copy link
Contributor

Choose a reason for hiding this comment

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

hooks should be a dependency?

Copy link
Member Author

Choose a reason for hiding this comment

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

I'm pretty sure this comes w/ dredd.

Copy link
Contributor

Choose a reason for hiding this comment

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

Nope, it doesn't.

Copy link
Member Author

Choose a reason for hiding this comment

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

Copy link
Member Author

Choose a reason for hiding this comment

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

And dredd add it on the fly when loading the hooks dynamically:
https://github.com/apiaryio/dredd/blob/master/src/add-hooks.coffee#L27

Copy link
Contributor

Choose a reason for hiding this comment

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

Ah, ok. I was strictly looking at dependencies. Weird way to do it but I can't complain. 👍

Copy link
Member Author

Choose a reason for hiding this comment

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

proxyquire FTW,

That's what they recommend in their doc, so I'm not guilty!
https://github.com/apiaryio/dredd/wiki/Writing-Hooks

Copy link

Choose a reason for hiding this comment

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

Add a comment explaining the magic. Otherwise, it may confuse the future maintainer.


hooks.before('Todos > Todo > Get a Todo', function(transaction, done) {
request.post({
uri: 'http://localhost:8080/todos',
json: {'text': 'do that'}
}, function(err, res, todo) {
transaction.fullPath = '/todos/' + todo.id;
return done();
});
});

hooks.before('Todos > Todo > Delete a Todo', function(transaction, done) {
request.post({
uri: 'http://localhost:8080/todos',
json: {'text': 'delete me'}
}, function(err, res, todo) {
transaction.fullPath = '/todos/' + todo.id;
return done();
});
});

hooks.after('Todos > Todo > Delete a Todo', function(transaction, done) {
request.get({
uri: 'http://localhost:8080' + transaction.fullPath,
}, function(err, res, body) {
console.assert(res.statusCode == 404);
return done();
});
});

hooks.after('Todos > Todos Collection > Archive done Todos', function(transaction, done) {
request.get({
uri: 'http://localhost:8080/todos'
}, function(err, res, body) {
JSON.parse(body).forEach(function(todo) {
console.assert(!todo.done);
});
return done();
});
});
77 changes: 77 additions & 0 deletions todos.apib
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
FORMAT: 1A

# Todos API

Todos API is a todo storage backend for [TodoMVC](//todomvc.com).

# Group Todos

# Todos Collection [/todos]

## Create a Todo [POST]

+ Request (application/json)

{
"text": "do this"
}

+ Response 201 (application/json; charset=utf-8)

{
"id": 42,
"text": "do this",
"done": false
}

## List all Todos [GET]

+ Response 200 (application/json; charset=utf-8)

[{
"id": 42,
"text": "do this",
"done": false
}]

## Archive done Todos [DELETE]

+ Response 204

# Todo [/todos/{id}]

+ Parameters
+ id (required, number, `42`)

## Get a Todo [GET]

+ Response 200 (application/json; charset=utf-8)

{
"id": 42,
"text": "do this",
"done": false
}


## Update a Todo [PUT]

+ Request (application/json)

{
"id": 42,
"text": "do this",
"done": true
}

+ Response 200 (application/json; charset=utf-8)

{
"id": 42,
"text": "do this",
"done": true
}

## Delete a Todo [DELETE]

+ Response 204
Loading