├── .editorconfig ├── .github ├── ISSUE_TEMPLATE.md └── PULL_REQUEST_TEMPLATE.md ├── .gitignore ├── .jshintignore ├── .jshintrc ├── .npmignore ├── LICENSE ├── README.md ├── client ├── README.md └── index.html ├── package.json ├── server ├── boot │ └── authentication.js ├── component-config.json ├── config.json ├── datasources.json ├── middleware.json ├── middleware │ └── custom-error.js ├── model-config.json └── server.js └── tests └── smoke.js /.editorconfig: -------------------------------------------------------------------------------- 1 | # EditorConfig helps developers define and maintain consistent 2 | # coding styles between different editors and IDEs 3 | # http://editorconfig.org 4 | 5 | root = true 6 | 7 | [*] 8 | indent_style = space 9 | indent_size = 2 10 | end_of_line = lf 11 | charset = utf-8 12 | trim_trailing_whitespace = true 13 | insert_final_newline = true 14 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE.md: -------------------------------------------------------------------------------- 1 | 8 | 9 | ### Bug or feature request 10 | 11 | 14 | 15 | - [ ] Bug 16 | - [ ] Feature request 17 | 18 | ### Description of feature (or steps to reproduce if bug) 19 | 20 | 21 | 22 | ### Link to sample repo to reproduce issue (if bug) 23 | 24 | 25 | 26 | ### Expected result 27 | 28 | 29 | 30 | ### Actual result (if bug) 31 | 32 | 33 | 34 | ### Additional information (Node.js version, LoopBack version, etc) 35 | 36 | 37 | -------------------------------------------------------------------------------- /.github/PULL_REQUEST_TEMPLATE.md: -------------------------------------------------------------------------------- 1 | ### Description 2 | 3 | 4 | #### Related issues 5 | 6 | 12 | 13 | - None 14 | 15 | ### Checklist 16 | 17 | 21 | 22 | - [ ] New tests added or existing tests modified to cover all changes 23 | - [ ] Code conforms with the [style 24 | guide](http://loopback.io/doc/en/contrib/style-guide.html) 25 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Logs 2 | logs 3 | *.log 4 | 5 | # Runtime data 6 | pids 7 | *.pid 8 | *.seed 9 | 10 | # Directory for instrumented libs generated by jscoverage/JSCover 11 | lib-cov 12 | 13 | # Coverage directory used by tools like istanbul 14 | coverage 15 | 16 | # Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files) 17 | .grunt 18 | 19 | # Compiled binary addons (http://nodejs.org/api/addons.html) 20 | build/Release 21 | 22 | # Dependency directory 23 | # Commenting this out is preferred by some people, see 24 | # https://www.npmjs.org/doc/misc/npm-faq.html#should-i-check-my-node_modules-folder-into-git- 25 | node_modules 26 | 27 | # Users Environment Variables 28 | .lock-wscript 29 | -------------------------------------------------------------------------------- /.jshintignore: -------------------------------------------------------------------------------- 1 | /client/ 2 | /node_modules/ 3 | -------------------------------------------------------------------------------- /.jshintrc: -------------------------------------------------------------------------------- 1 | { 2 | "node": true, 3 | "esnext": true, 4 | "bitwise": true, 5 | "camelcase": true, 6 | "eqeqeq": true, 7 | "eqnull": true, 8 | "immed": true, 9 | "indent": 2, 10 | "latedef": "nofunc", 11 | "newcap": true, 12 | "nonew": true, 13 | "noarg": true, 14 | "quotmark": "single", 15 | "regexp": true, 16 | "undef": true, 17 | "unused": false, 18 | "trailing": true, 19 | "sub": true, 20 | "maxlen": 80 21 | } 22 | -------------------------------------------------------------------------------- /.npmignore: -------------------------------------------------------------------------------- 1 | .idea 2 | .project 3 | *.sublime-* 4 | .DS_Store 5 | *.seed 6 | *.log 7 | *.csv 8 | *.dat 9 | *.out 10 | *.pid 11 | *.swp 12 | *.swo 13 | node_modules 14 | coverage 15 | *.tgz 16 | *.xml 17 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) IBM Corp. 2014,2016. All Rights Reserved. 2 | Node module: loopback-example-middleware 3 | This project is licensed under the MIT License, full text below. 4 | 5 | -------- 6 | 7 | MIT license 8 | 9 | Permission is hereby granted, free of charge, to any person obtaining a copy 10 | of this software and associated documentation files (the "Software"), to deal 11 | in the Software without restriction, including without limitation the rights 12 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 13 | copies of the Software, and to permit persons to whom the Software is 14 | furnished to do so, subject to the following conditions: 15 | 16 | The above copyright notice and this permission notice shall be included in 17 | all copies or substantial portions of the Software. 18 | 19 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 20 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 21 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 22 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 23 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 24 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 25 | THE SOFTWARE. 26 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # loopback-example-middleware 2 | ``` 3 | $ git clone git@github.com:strongloop/loopback-example-middleware.git 4 | $ cd loopback-example-middleware 5 | $ npm install 6 | $ node . 7 | ``` 8 | 9 | - [How do you serve static content via static middleware?](https://github.com/strongloop/loopback-example-middleware#how-do-you-serve-static-content-via-static-middleware) 10 | 11 | ## How do you serve static content via static middleware? 12 | 1. Add static middleware to the [files property](https://github.com/strongloop/loopback-example-middleware/blob/master/server/middleware.json#L17-L19) in middleware.json 13 | 2. Delete [`server/boot/root.js`](https://github.com/strongloop/loopback-example-middleware/blob/master/server/boot). 14 | 3. Create [`client/index.html`](https://github.com/strongloop/loopback-example-middleware/blob/master/client/index.html) 15 | 4. Start the server via `node .` and browse to [`localhost:3000`](http://localhost:3000). You should see `hello world` being served. 16 | 17 | ## How do you create a custom error message for all errors? 18 | 1. Create a [single function](https://github.com/strongloop/loopback-example-middleware/blob/master/server/server.js#L33-l41) that all errors are passed to. 19 | 2. Set [`app.get('remoting').errorHandler`](https://github.com/strongloop/loopback-example-middleware/blob/master/server/server.js#L23-l31) to call a custom error handler. 20 | 3. Create a [`custom error middleware`](https://github.com/strongloop/loopback-example-middleware/blob/master/server/middleware/custom-error.js) to handle errors not thrown by the `loopback.rest()` middleware. 21 | 22 | **Note: you must register your custom error handler in the [middleware.json](https://github.com/strongloop/loopback-example-middleware/blob/master/server/middleware.json#L25) config file.** 23 | 24 | --- 25 | 26 | [More LoopBack examples](https://loopback.io/doc/en/lb3/Tutorials-and-examples.html) 27 | -------------------------------------------------------------------------------- /client/README.md: -------------------------------------------------------------------------------- 1 | ## Client 2 | 3 | This is the place for your application front-end files. 4 | -------------------------------------------------------------------------------- /client/index.html: -------------------------------------------------------------------------------- 1 | hello world 2 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "loopback-example-middleware", 3 | "version": "1.0.0", 4 | "main": "server/server.js", 5 | "scripts": { 6 | "pretest": "jshint .", 7 | "start": "node .", 8 | "test": "tape tests/**/*.js" 9 | }, 10 | "dependencies": { 11 | "compression": "^1.0.3", 12 | "cors": "^2.8.1", 13 | "loopback": "^3.0.0", 14 | "loopback-boot": "^2.4.0", 15 | "loopback-datasource-juggler": "^2.7.0", 16 | "serve-favicon": "^2.0.1", 17 | "strong-error-handler": "^1.1.1" 18 | }, 19 | "optionalDependencies": { 20 | "loopback-component-explorer": "^2.1.0" 21 | }, 22 | "devDependencies": { 23 | "jshint": "^2.5.6", 24 | "tape": "^4.2.0" 25 | }, 26 | "repository": { 27 | "type": "git", 28 | "url": "https://github.com/strongloop/loopback-example-middleware" 29 | }, 30 | "description": "loopback-example-middleware", 31 | "license": "MIT" 32 | } 33 | -------------------------------------------------------------------------------- /server/boot/authentication.js: -------------------------------------------------------------------------------- 1 | // Copyright IBM Corp. 2014. All Rights Reserved. 2 | // Node module: loopback-example-middleware 3 | // This file is licensed under the MIT License. 4 | // License text available at https://opensource.org/licenses/MIT 5 | 6 | module.exports = function enableAuthentication(server) { 7 | // enable authentication 8 | server.enableAuth(); 9 | }; 10 | -------------------------------------------------------------------------------- /server/component-config.json: -------------------------------------------------------------------------------- 1 | { 2 | "loopback-component-explorer": { 3 | "mountPath": "/explorer" 4 | } 5 | } -------------------------------------------------------------------------------- /server/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "restApiRoot": "/api", 3 | "host": "0.0.0.0", 4 | "port": 3000, 5 | "remoting": { 6 | "context": false, 7 | "rest": { 8 | "normalizeHttpPath": false, 9 | "xml": false 10 | }, 11 | "json": { 12 | "strict": false, 13 | "limit": "100kb" 14 | }, 15 | "urlencoded": { 16 | "extended": true, 17 | "limit": "100kb" 18 | }, 19 | "cors": false, 20 | "handleErrors": false 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /server/datasources.json: -------------------------------------------------------------------------------- 1 | { 2 | "db": { 3 | "name": "db", 4 | "connector": "memory" 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /server/middleware.json: -------------------------------------------------------------------------------- 1 | { 2 | "initial:before": { 3 | "loopback#favicon": {} 4 | }, 5 | "initial": { 6 | "compression": {}, 7 | "cors": { 8 | "params": { 9 | "origin": true, 10 | "credentials": true, 11 | "maxAge": 86400 12 | } 13 | } 14 | }, 15 | "session": { 16 | }, 17 | "auth": { 18 | }, 19 | "parse": { 20 | }, 21 | "routes": { 22 | "loopback#rest": { 23 | "paths": ["${restApiRoot}"] 24 | } 25 | }, 26 | "files": { 27 | "loopback#static": { 28 | "params": "$!../client" 29 | } 30 | }, 31 | "final": { 32 | "loopback#urlNotFound": {} 33 | }, 34 | "final:after": { 35 | "./middleware/custom-error": {}, 36 | "strong-error-handler": {} 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /server/middleware/custom-error.js: -------------------------------------------------------------------------------- 1 | // Copyright IBM Corp. 2015. All Rights Reserved. 2 | // Node module: loopback-example-middleware 3 | // This file is licensed under the MIT License. 4 | // License text available at https://opensource.org/licenses/MIT 5 | 6 | module.exports = function() { 7 | return function(err, req, res, next) { 8 | err = req.app.buildError(err); 9 | next(err); 10 | }; 11 | }; 12 | -------------------------------------------------------------------------------- /server/model-config.json: -------------------------------------------------------------------------------- 1 | { 2 | "_meta": { 3 | "sources": [ 4 | "loopback/common/models", 5 | "loopback/server/models", 6 | "../common/models", 7 | "./models" 8 | ] 9 | }, 10 | "User": { 11 | "dataSource": "db" 12 | }, 13 | "AccessToken": { 14 | "dataSource": "db", 15 | "public": false 16 | }, 17 | "ACL": { 18 | "dataSource": "db", 19 | "public": false 20 | }, 21 | "RoleMapping": { 22 | "dataSource": "db", 23 | "public": false 24 | }, 25 | "Role": { 26 | "dataSource": "db", 27 | "public": false 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /server/server.js: -------------------------------------------------------------------------------- 1 | // Copyright IBM Corp. 2014,2015. All Rights Reserved. 2 | // Node module: loopback-example-middleware 3 | // This file is licensed under the MIT License. 4 | // License text available at https://opensource.org/licenses/MIT 5 | 6 | var loopback = require('loopback'); 7 | var boot = require('loopback-boot'); 8 | 9 | var app = module.exports = loopback(); 10 | 11 | app.start = function() { 12 | // start the web server 13 | return app.listen(function() { 14 | app.emit('started'); 15 | var baseUrl = app.get('url').replace(/\/$/, ''); 16 | console.log('Web server listening at: %s', baseUrl); 17 | if (app.get('loopback-component-explorer')) { 18 | var explorerPath = app.get('loopback-component-explorer').mountPath; 19 | console.log('Browse your REST API at %s%s', baseUrl, explorerPath); 20 | } 21 | }); 22 | }; 23 | 24 | // Bootstrap the application, configure models, datasources and middleware. 25 | // Sub-apps like REST API are mounted via boot scripts. 26 | boot(app, __dirname, function(err) { 27 | if (err) throw err; 28 | 29 | // start the server if `$ node server.js` 30 | if (require.main === module) 31 | app.start(); 32 | }); 33 | 34 | app.get('remoting').errorHandler = { 35 | handler: function(err, req, res, defaultHandler) { 36 | err = app.buildError(err); 37 | 38 | // send the error back to the original handler 39 | defaultHandler(err); 40 | }, 41 | disableStackTrace: true 42 | }; 43 | 44 | app.buildError = function(err) { 45 | err.message = 'Custom message: ' + err.message; 46 | err.status = 408; // override the status 47 | 48 | // remove the statusCode property 49 | delete err.statusCode; 50 | 51 | return err; 52 | }; 53 | -------------------------------------------------------------------------------- /tests/smoke.js: -------------------------------------------------------------------------------- 1 | // Copyright IBM Corp. 2015. All Rights Reserved. 2 | // Node module: loopback-example-middleware 3 | // This file is licensed under the MIT License. 4 | // License text available at https://opensource.org/licenses/MIT 5 | 6 | var test = require('tape'); 7 | 8 | test('smoke test', function(t) { 9 | t.plan(1); 10 | t.equal(1, 1); 11 | }); 12 | --------------------------------------------------------------------------------