Skip to content

Commit

Permalink
Added example app
Browse files Browse the repository at this point in the history
update .gitignore

added README.md for the example application
  • Loading branch information
sebelga committed Aug 26, 2017
1 parent 32634a5 commit b2c752c
Show file tree
Hide file tree
Showing 17 changed files with 2,249 additions and 0 deletions.
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -35,3 +35,6 @@ entity_old.js
.trash
config.json
.coveralls.yml

.env
gae_credentials.json
14 changes: 14 additions & 0 deletions .vscode/launch.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,20 @@
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
"version": "0.2.0",
"configurations": [
{
"type": "node",
"request": "launch",
"name": "Example app",
"runtimeExecutable": "nodemon",
"cwd": "${workspaceRoot}/example",
"program": "${workspaceRoot}/example/app/server.js",
"restart": true,
"console": "integratedTerminal",
"internalConsoleOptions": "neverOpen",
"env": {
"NODE_ENV": "development"
}
},
{
"type": "node",
"request": "launch",
Expand Down
7 changes: 7 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ It is built on top of [gcloud-node](https://github.com/GoogleCloudPlatform/gclou
- [Motivation](#motivation)
- [Installation](#installation)
- [What do I get from it?](#what-do-i-get-from-it)
- [Demo Application](#demo-application)
- [Getting Started](#getting-started)
- [settings](#settings)
- [Create an API for an Entity](#create-an-api-for-an-entity)
Expand Down Expand Up @@ -74,6 +75,12 @@ app.use('/api/v1', blogPostApi);

-----

## Demo Application

Inside the "example" folder you will find a running application to demostrate how to use gstore-api. Follow the instruction in the [README](./example/README.md) file.

-----

## Getting Started

### settings
Expand Down
113 changes: 113 additions & 0 deletions example/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
# gstore-api App example

Small application to demostrate how to use gstore-api

<!-- START doctoc generated TOC please keep comment here to allow auto update -->
<!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE -->

- [gstore-api App example](#gstore-api-app-example)
- [Launch the app](#launch-the-app)
- [What does it do](#what-does-it-do)
- [Test the API](#test-the-api)
- [List all users](#list-all-users)
- [Get a user](#get-a-user)
- [Create a user](#create-a-user)
- [Update a user](#update-a-user)
- [Delete a user](#delete-a-user)
- [Delete ALL users](#delete-all-users)
- [User login](#user-login)

<!-- END doctoc generated TOC please keep comment here to allow auto update -->

## Launch the app

1. Install the dependencies

```js
npm install
```

2. Create a file named ".env" at the root of the example folder.
Put inside the file these 2 environment variables:

```
GCLOUD_PROJECT=name-of-your-project
GOOGLE_APPLICATION_CREDENTIALS=/absolute/path/to/your/credentials.json
```

3. Launch the server (better with nodemon). Inside the example folder run:

```js
NODE_ENV=development nodemon app/server.js
```

## What does it do

- It will generate an API to list, create, update and delete Users
- Create an /auth/login route to log a user in

Once the server is launched you can access it at `http://localhost:3007`.

### Test the API

To test the API I recommend [Postman](https://www.getpostman.com/) but any API tool will do.

#### List all users

`GET /api/v1/users`

#### Get a user

`GET /api/v1/users/{id}`

#### Create a user

`POST /api/v1/users`

Here you can either just pass a raw JSON object with the following properties (don't forget to set the "Content-type" Header to "application/json":

- username (required)
- password (required)
- firstname
- lastname
- email

Or you can also **upload a file** (simulated in the modules/user/user.controller.js) by setting the body type of the Request to *form-data* and add a "profilePict" field (of type **File**). As the username and password are required you also need to pass a "username" and "password" field (of type **Text**).

#### Update a user

`PATCH /api/v1/users/{id}`

Modify the properties of a specific User.
Like with "create" above you can either update the user by sending a raw JSON object, or also by uploading a file (through form-data fields).

#### Delete a user

`DELETE /api/v1/users/{id}`

Delete a User at the specific id.

#### Delete ALL users

`DELETE /api/v1/users`

Delete all the users in the Datastore.

### User login

The demo application also shows you how you can login a user with the following route:

```js
POST /auth/login
```

and by passing a JSON object in the body of the request

```js
{
"username": "john",
"password": "your-password"
}
```

If the username and password are correct you should receive a dummy token back.
18 changes: 18 additions & 0 deletions example/app/db.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
'use strict';

/**
* The configuration of the Datastore comes from 2 environment variables
* GCLOUD_PROJECT
* GOOGLE_APPLICATION_CREDENTIALS
*
* See "server.js" for more info
*/

const gstore = require('gstore-node');
const datastore = require('@google-cloud/datastore')();

const connectDatastore = () => gstore.connect(datastore);

module.exports = {
connectDatastore,
};
10 changes: 10 additions & 0 deletions example/app/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
'use strict';

const express = require('express');

const app = express();

// routes
require('./routes')(app);

module.exports = app;
40 changes: 40 additions & 0 deletions example/app/modules/auth/authentication.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
'use strict';

const User = require('../user').User;

const login = (req, res) => {
const username = req.body.username;
const password = req.body.password;

if (typeof username === 'undefined') {
return res.status(403).json({ message: 'Username is missing' });
}

return User.findOne({ username })
.then((user) => {
// "user" is a gstore entity instance
// we call the cusom method in its schema
return user.verifyPassword(password)
.then((match) => {
if (!match) {
return res.status(403).json({ message: 'Authentication failed' });
}

// Authentication success
const token = '1234'; // // Here you would probably generate a Json Web Token

return res.json({ token });
});
})
.catch((err) => {
if (err.code === 404) {
return res.status(403).json({
message: 'Authentication failed',
});
}

return res.status(400).json({ message: err.message || 'Server login error.' });
});
};

module.exports = { login };
6 changes: 6 additions & 0 deletions example/app/modules/auth/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
'use strict';

const authentication = require('./authentication');
const routes = require('./routes');

module.exports = { authentication, routes };
12 changes: 12 additions & 0 deletions example/app/modules/auth/routes.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
'use strict';


const bodyParser = require('body-parser');

const router = require('express').Router();

const auth = require('./authentication');

router.post('/auth/login', bodyParser.json(), auth.login);

module.exports = router;
9 changes: 9 additions & 0 deletions example/app/modules/user/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
'use strict';

const User = require('./user.model');
const routes = require('./routes');

module.exports = {
User,
routes,
};
47 changes: 47 additions & 0 deletions example/app/modules/user/routes.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
'use strict';

const multer = require('multer');
const router = require('express').Router();
const gstoreApi = require('gstore-api')(); // import unique instance of gstoreApi

// model & controller
const User = require('./user.model');
const user = require('./user.controller');

// Configure Multer file upload
const storage = multer.memoryStorage();
const upload = multer({ storage });

// Tell the gstore-api instance to use our Express router
const apiBuilder = gstoreApi.express(router);

// Settings for our API routes
const settings = {
operations: {
create: {
middleware: [upload.single('profilePict')], // Add a middleware to this route ("multer" file upload)
handler: user.create, // custom handler for the "Create User" route ("POST /users")
},
// udpatePatch: { middleware: [upload.single('profilePict')], handler: user.update },
updatePatch: { middleware: [upload.single('profilePict')], handler: user.update },
// updateReplace: { exec: false },
deleteAll: { exec: true }, // we enable the "DELETE ALL" route. (disabled by default)
},
};

// Generate API
const routes = apiBuilder.create(User, settings);

module.exports = routes;

/**
* gstore-api routes generated
* ---------------------------
* GET /users --> GET all users
* GET /users/{id} --> GET a unique user
* POST /users --> create a User
* PUT /users/{id} --> Update (and replace) a User at a specific id
* PATCH /users/{id} --> Update a User at a specific id
* DELETE /users/{id} --> Delete specific User
* DELETE /users --> Delete ALL Users
*/
Loading

0 comments on commit b2c752c

Please sign in to comment.