Skip to content

Commit d800ff8

Browse files
authored
Enhanced support for batch endpoints (#3042)
* Allow to have different endpoint on publicserverURL and serverURL when batching * nits
1 parent 8c2c76d commit d800ff8

File tree

2 files changed

+96
-14
lines changed

2 files changed

+96
-14
lines changed

spec/batch.spec.js

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
var batch = require('../src/batch');
2+
3+
const originalURL = '/parse/batch';
4+
const serverURL = 'http://localhost:1234/parse';
5+
const serverURL1 = 'http://localhost:1234/1';
6+
const serverURLNaked = 'http://localhost:1234/';
7+
const publicServerURL = 'http://domain.com/parse';
8+
const publicServerURLNaked = 'http://domain.com/';
9+
10+
describe('batch', () => {
11+
it('should return the proper url', () => {
12+
let internalURL = batch.makeBatchRoutingPathFunction(originalURL)('/parse/classes/Object');
13+
14+
expect(internalURL).toEqual('/classes/Object');
15+
});
16+
17+
it('should return the proper url same public/local endpoint', () => {
18+
let originalURL = '/parse/batch';
19+
let internalURL = batch.makeBatchRoutingPathFunction(originalURL, serverURL, publicServerURL)('/parse/classes/Object');
20+
21+
expect(internalURL).toEqual('/classes/Object');
22+
});
23+
24+
it('should return the proper url with different public/local mount', () => {
25+
let originalURL = '/parse/batch';
26+
let internalURL = batch.makeBatchRoutingPathFunction(originalURL, serverURL1, publicServerURL)('/parse/classes/Object');
27+
28+
expect(internalURL).toEqual('/classes/Object');
29+
});
30+
31+
it('should return the proper url with naked public', () => {
32+
let originalURL = '/batch';
33+
let internalURL = batch.makeBatchRoutingPathFunction(originalURL, serverURL, publicServerURLNaked)('/classes/Object');
34+
35+
expect(internalURL).toEqual('/classes/Object');
36+
});
37+
38+
it('should return the proper url with naked local', () => {
39+
let originalURL = '/parse/batch';
40+
let internalURL = batch.makeBatchRoutingPathFunction(originalURL, serverURLNaked, publicServerURL)('/parse/classes/Object');
41+
42+
expect(internalURL).toEqual('/classes/Object');
43+
});
44+
});

src/batch.js

Lines changed: 52 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
1-
var Parse = require('parse/node').Parse;
2-
1+
const Parse = require('parse/node').Parse;
2+
const url = require('url');
3+
const path = require('path');
34
// These methods handle batch requests.
4-
var batchPath = '/batch';
5+
const batchPath = '/batch';
56

67
// Mounts a batch-handler onto a PromiseRouter.
78
function mountOnto(router) {
@@ -10,6 +11,48 @@ function mountOnto(router) {
1011
});
1112
}
1213

14+
function parseURL(URL) {
15+
if (typeof URL === 'string') {
16+
return url.parse(URL)
17+
}
18+
return undefined;
19+
}
20+
21+
function makeBatchRoutingPathFunction(originalUrl, serverURL, publicServerURL) {
22+
serverURL = serverURL ? parseURL(serverURL) : undefined;
23+
publicServerURL = publicServerURL ? parseURL(publicServerURL): undefined;
24+
25+
let apiPrefixLength = originalUrl.length - batchPath.length;
26+
let apiPrefix = originalUrl.slice(0, apiPrefixLength);
27+
28+
let makeRoutablePath = function(requestPath) {
29+
// The routablePath is the path minus the api prefix
30+
if (requestPath.slice(0, apiPrefix.length) != apiPrefix) {
31+
throw new Parse.Error(
32+
Parse.Error.INVALID_JSON,
33+
'cannot route batch path ' + requestPath);
34+
}
35+
return path.join('/', requestPath.slice(apiPrefix.length));
36+
}
37+
38+
if (serverURL && publicServerURL
39+
&& (serverURL.path != publicServerURL.path)) {
40+
let localPath = serverURL.path;
41+
let publicPath = publicServerURL.path;
42+
// Override the api prefix
43+
apiPrefix = localPath;
44+
return function(requestPath) {
45+
// Build the new path by removing the public path
46+
// and joining with the local path
47+
let newPath = path.join('/', localPath, '/' , requestPath.slice(publicPath.length));
48+
// Use the method for local routing
49+
return makeRoutablePath(newPath);
50+
}
51+
}
52+
53+
return makeRoutablePath;
54+
}
55+
1356
// Returns a promise for a {response} object.
1457
// TODO: pass along auth correctly
1558
function handleBatch(router, req) {
@@ -26,19 +69,13 @@ function handleBatch(router, req) {
2669
if (!req.originalUrl.endsWith(batchPath)) {
2770
throw 'internal routing problem - expected url to end with batch';
2871
}
29-
var apiPrefixLength = req.originalUrl.length - batchPath.length;
30-
var apiPrefix = req.originalUrl.slice(0, apiPrefixLength);
72+
73+
const makeRoutablePath = makeBatchRoutingPathFunction(req.originalUrl, req.config.serverURL, req.config.publicServerURL);
3174

3275
const promises = req.body.requests.map((restRequest) => {
33-
// The routablePath is the path minus the api prefix
34-
if (restRequest.path.slice(0, apiPrefixLength) != apiPrefix) {
35-
throw new Parse.Error(
36-
Parse.Error.INVALID_JSON,
37-
'cannot route batch path ' + restRequest.path);
38-
}
39-
var routablePath = restRequest.path.slice(apiPrefixLength);
76+
const routablePath = makeRoutablePath(restRequest.path);
4077
// Construct a request that we can send to a handler
41-
var request = {
78+
const request = {
4279
body: restRequest.body,
4380
config: req.config,
4481
auth: req.auth,
@@ -58,5 +95,6 @@ function handleBatch(router, req) {
5895
}
5996

6097
module.exports = {
61-
mountOnto: mountOnto
98+
mountOnto,
99+
makeBatchRoutingPathFunction
62100
};

0 commit comments

Comments
 (0)