Skip to content

Commit 5d4fb45

Browse files
committed
Merge pull request #86 from digitalsadhu/add/option_to_scope_method
Add/option to scope method
2 parents 185e96f + 7b6cb26 commit 5d4fb45

File tree

12 files changed

+320
-23
lines changed

12 files changed

+320
-23
lines changed

README.md

Lines changed: 51 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,14 @@ Example:
6767
"loopback-component-jsonapi": {
6868
"restApiRoot": "/api",
6969
"enable": true,
70-
"handleErrors": true
70+
"handleErrors": true,
71+
"exclude": [
72+
{"model": "comment"},
73+
{"methods": "find"},
74+
{"model": "post", "methods": "find"},
75+
{"model": "person", "methods": ["find", "create"]}
76+
],
77+
"hideIrrelevantMethods": true
7178
}
7279
}
7380
```
@@ -87,6 +94,49 @@ format. Validation errors include the correct properties in order to work
8794
out of the box with ember.
8895
Default: true
8996

97+
### exclude
98+
Allows blacklisting of models and methods. (See example above)
99+
Define an array of blacklist objects. Blacklist objects can contain "model" key
100+
"methods" key or both. If just "model" is defined then all methods for the
101+
specified model will not use jsonapi. If just the "methods" key is defined then
102+
all methods specified on all models will be not use jsonapi. If a combination of
103+
"model" and "methods" keys are used then the specific combination of model and methods
104+
specified will not use jsonapi.
105+
106+
#### Please note
107+
The default component behavior currently is to only modify the output of the following
108+
methods on all models to be json api compliant:
109+
- find
110+
- create
111+
- updateAttributes
112+
- deleteById
113+
- findById
114+
- __get__.*
115+
- __findRelationships__.*
116+
117+
And the default current behavior for modifying input only applies to the following methods on
118+
all models:
119+
- create
120+
- updateAttributes
121+
122+
Type: array
123+
Default: null
124+
125+
### hideIrrelevantMethods
126+
By default, loopback-component-jsonapi disables a number of methods from each endpoint
127+
that are not jsonapi relevant. These methods are:
128+
- upsert
129+
- exists
130+
- findOne
131+
- count
132+
- createChangeStream
133+
- updateAll
134+
You can use this option to reenable these methods.
135+
Please note, these methods will not be modified by the component and so their output
136+
will not be in a jsonapi compliant format.
137+
Type: boolean
138+
Default: true
139+
90140
## Debugging
91141
You can enable debug logging by setting an environment variable:
92142
DEBUG=loopback-component-jsonapi

lib/create.js

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
var url = require('url');
2+
var utils = require('./utils');
23

34
module.exports = function (app, options) {
45
//get remote methods.
@@ -9,6 +10,10 @@ module.exports = function (app, options) {
910
//register after remote method hook on all methods
1011
remotes.after('**', function (ctx, next) {
1112

13+
if (utils.shouldNotApplyJsonApi(ctx, options)) {
14+
return next();
15+
};
16+
1217
//in this case we are only interested in handling create operations.
1318
if (ctx.method.name === 'create') {
1419
//JSON API specifies that created resources should have the

lib/delete.js

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
var utils = require('./utils');
2+
13
module.exports = function (app, options) {
24
//get remote methods.
35
//set strong-remoting for more information
@@ -7,6 +9,10 @@ module.exports = function (app, options) {
79
//register after remote method hook on all methods
810
remotes.after('**', function (ctx, next) {
911

12+
if (utils.shouldNotApplyJsonApi(ctx, options)) {
13+
return next();
14+
};
15+
1016
//in this case we are only interested in handling create operations.
1117
if (ctx.method.name === 'deleteById') {
1218
//JSON API specifies that successful

lib/deserialize.js

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3,23 +3,26 @@ var deserializer = require('./deserializer');
33
var RelUtils = require('./utilities/relationship-utils');
44
var utils = require('./utils');
55

6-
module.exports = function (app) {
6+
module.exports = function (app, options) {
77
/**
88
* Register a handler to run before all remote methods so that we can
99
* transform JSON API structured JSON payload into something loopback
1010
* can work with.
1111
*/
1212
app.remotes().before('**', function (ctx, next) {
1313
var data, serverRelations, errors;
14+
15+
if (utils.shouldNotApplyJsonApi(ctx, options)) {
16+
return next();
17+
};
18+
1419
var regexs = [
15-
/\.create/,
16-
/prototype\.updateAttributes/,
17-
/prototype\.__createRelationships__/,
18-
/prototype\.__updateRelationships__/
20+
/^create$/,
21+
/^updateAttributes$/
1922
];
2023

2124
var matches = regexs.filter(function (regex) {
22-
return ctx.methodString.match(regex);
25+
return regex.test(ctx.method.name);
2326
});
2427

2528
if (matches.length > 0) {

lib/headers.js

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,17 @@
11
'use strict';
22
var is = require('type-is');
33
var _ = require('lodash');
4+
var utils = require('./utils');
45

56
module.exports = function (app, options) {
67
var remotes = app.remotes();
78

89
remotes.before('**', function (ctx, next) {
10+
11+
if (utils.shouldNotApplyJsonApi(ctx, options)) {
12+
return next();
13+
};
14+
915
// We must force `application/json` until we can override it through strong remoting
1016
if (ctx.req.accepts('application/vnd.api+json')) {
1117
ctx.req.headers.accept = 'application/json';

lib/relationships.js

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,10 @@ module.exports = function (app, options) {
1212

1313
remotes.before('**', function (ctx, next) {
1414

15+
if (utils.shouldNotApplyJsonApi(ctx, options)) {
16+
return next();
17+
};
18+
1519
id = ctx.req.params.id;
1620
data = ctx.args.data;
1721
model = utils.getModelFromContext(ctx, app);
@@ -23,6 +27,10 @@ module.exports = function (app, options) {
2327
// for create
2428
remotes.after('**', function (ctx, next) {
2529

30+
if (utils.shouldNotApplyJsonApi(ctx, options)) {
31+
return next();
32+
};
33+
2634
if (ctx.result) {
2735
id = ctx.result.id;
2836
data = ctx.req.body;

lib/removeRemoteMethods.js

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,11 @@ module.exports = function (app, options) {
55
//does not support.
66
var isStatic = true;
77

8-
Object.keys(models).forEach(function (model) {
9-
['upsert', 'exists', 'findOne', 'count', 'createChangeStream', 'updateAll'].forEach(function (method) {
10-
models[model].disableRemoteMethod(method, isStatic);
8+
if (options.hideIrrelevantMethods !== false) {
9+
Object.keys(models).forEach(function (model) {
10+
['upsert', 'exists', 'findOne', 'count', 'createChangeStream', 'updateAll'].forEach(function (method) {
11+
models[model].disableRemoteMethod(method, isStatic);
12+
});
1113
});
12-
});
14+
}
1315
};

lib/serialize.js

Lines changed: 12 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -3,15 +3,13 @@ var serializer = require('./serializer');
33
var utils = require('./utils');
44
var _ = require('lodash');
55
var regexs = [
6-
/\.find/,
7-
/\.create/,
8-
/\.deleteById/,
9-
/\.findById/,
10-
/prototype\.__get__/,
11-
/prototype\.updateAttributes/,
12-
/prototype\.__findRelationships__/,
13-
/prototype\.__createRelationships__/,
14-
/prototype\.__updateRelationships__/
6+
/^find$/,
7+
/^create$/,
8+
/^deleteById$/,
9+
/^findById$/,
10+
/^__get__.*/,
11+
/^updateAttributes$/,
12+
/^__findRelationships__.*/
1513
];
1614

1715
module.exports = function (app, defaults) {
@@ -26,8 +24,12 @@ module.exports = function (app, defaults) {
2624
model,
2725
requestedIncludes;
2826

27+
if (utils.shouldNotApplyJsonApi(ctx, defaults)) {
28+
return next();
29+
};
30+
2931
var matches = regexs.filter(function (regex) {
30-
return ctx.methodString.match(regex);
32+
return regex.test(ctx.method.name);
3133
});
3234

3335
if (!matches.length) {

lib/update.js

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,14 @@
1+
var utils = require('./utils');
2+
13
module.exports = function (app, options) {
24
var remotes = app.remotes();
35

46
remotes.after('**', function (ctx, next) {
7+
8+
if (utils.shouldNotApplyJsonApi(ctx, options)) {
9+
return next();
10+
};
11+
512
if (ctx.method.name === 'updateAttributes') {
613
// remote links object from resource response
714
delete ctx.result.links;

lib/utils.js

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
var url = require('url');
22
var inflection = require('inflection');
3+
var _ = require('lodash');
34

45
/**
56
* Public API
@@ -13,7 +14,8 @@ module.exports = {
1314
modelNameFromContext: modelNameFromContext,
1415
pluralForModel: pluralForModel,
1516
urlFromContext: urlFromContext,
16-
primaryKeyForModel: primaryKeyForModel
17+
primaryKeyForModel: primaryKeyForModel,
18+
shouldNotApplyJsonApi: shouldNotApplyJsonApi
1719
};
1820

1921
function primaryKeyForModel (model) {
@@ -164,3 +166,22 @@ function buildModelUrl (protocol, host, apiRoot, modelName, id) {
164166

165167
return result;
166168
}
169+
170+
function shouldNotApplyJsonApi (ctx, options) {
171+
//handle options.exclude
172+
if (!options.exclude) return false;
173+
174+
var modelName = ctx.method.sharedClass.name;
175+
var methodName = ctx.method.name;
176+
var model;
177+
var methods;
178+
for (var i = 0; i < options.exclude.length; i++) {
179+
model = options.exclude[i].model;
180+
methods = options.exclude[i].methods;
181+
if (model === modelName && !methods) return true;
182+
if (!model && methods === methodName) return true;
183+
if (model === modelName && methods === methodName) return true;
184+
if (model === modelName && _.contains(methods, methodName)) return true;
185+
}
186+
return false;
187+
}

0 commit comments

Comments
 (0)