moleculer-web
Advanced tools
Comparing version 0.3.0 to 0.3.1
@@ -0,1 +1,38 @@ | ||
<a name="0.3.1"></a> | ||
# 0.3.1 (2017-06-02) | ||
## New | ||
### RESTful routes | ||
It is possible to use RESTful aliases which routed to CRUD service actions. | ||
**Usage** | ||
```js | ||
broker.createService(ApiGatewayService, { | ||
settings: { | ||
routes: [{ | ||
// RESTful aliases | ||
aliases: { | ||
"REST posts": "posts" | ||
} | ||
}] | ||
} | ||
}); | ||
// Start server | ||
broker.start(); | ||
``` | ||
The `"REST posts": "posts"` will be extracted to these aliases: | ||
```js | ||
"GET posts": "posts.find", | ||
"GET posts/:id": "posts.get", | ||
"POST posts": "posts.create", | ||
"PUT posts/:id": "posts.update", | ||
"DELETE posts/:id": "posts.remove" | ||
``` | ||
Example: [examples/rest](/examples/rest) | ||
----------------------------- | ||
<a name="0.3.0"></a> | ||
@@ -2,0 +39,0 @@ # 0.3.0 (2017-06-01) |
{ | ||
"name": "moleculer-web", | ||
"version": "0.3.0", | ||
"version": "0.3.1", | ||
"description": "Official API Gateway service for Moleculer framework", | ||
@@ -5,0 +5,0 @@ "main": "index.js", |
@@ -20,3 +20,3 @@ [![Moleculer logo](http://moleculer.services/images/banner.png)](https://github.com/ice-services/moleculer) | ||
* multiple routes | ||
* alias names (with named parameters) | ||
* alias names (with named parameters & REST shorthand) | ||
* whitelist | ||
@@ -23,0 +23,0 @@ * multiple body parsers (json, urlencoded) |
@@ -123,3 +123,2 @@ /* | ||
// Handle whitelist | ||
@@ -152,2 +151,43 @@ route.whitelist = opts.whitelist; | ||
const createAliasedRoute = (action, matchPath) => { | ||
let method = "*"; | ||
if (matchPath.indexOf(" ") !== -1) { | ||
const p = matchPath.split(" "); | ||
method = p[0]; | ||
matchPath = p[1]; | ||
} | ||
if (matchPath.startsWith("/")) | ||
matchPath = matchPath.slice(1); | ||
let keys = []; | ||
const re = pathToRegexp(matchPath, keys, {}); // Options: https://github.com/pillarjs/path-to-regexp#usage | ||
this.logger.info(` Alias: ${method} ${route.path + (route.path.endsWith("/") ? "": "/")}${matchPath} -> ${action}`); | ||
return { | ||
action, | ||
method, | ||
re, | ||
match: url => { | ||
const m = re.exec(url); | ||
if (!m) return false; | ||
const params = {}; | ||
let key, param; | ||
for (let i = 0; i < keys.length; i++) { | ||
key = keys[i]; | ||
param = m[i + 1]; | ||
if (!param) continue; | ||
params[key.name] = decodeParam(param); | ||
if (key.repeat) | ||
params[key.name] = params[key.name].split(key.delimiter); | ||
} | ||
return params; | ||
} | ||
}; | ||
}; | ||
// Handle aliases | ||
@@ -157,39 +197,16 @@ if (opts.aliases && Object.keys(opts.aliases).length > 0) { | ||
_.forIn(opts.aliases, (action, matchPath) => { | ||
let method = "*"; | ||
if (matchPath.indexOf(" ") !== -1) { | ||
if (matchPath.startsWith("REST")) { | ||
const p = matchPath.split(" "); | ||
method = p[0]; | ||
matchPath = p[1]; | ||
} | ||
if (matchPath.startsWith("/")) | ||
matchPath = matchPath.slice(1); | ||
const pathName = p[1]; | ||
let keys = []; | ||
const re = pathToRegexp(matchPath, keys, {}); // Options: https://github.com/pillarjs/path-to-regexp#usage | ||
// Generate RESTful API. More info http://www.restapitutorial.com/ | ||
route.aliases.push(createAliasedRoute(`${action}.find`, `GET ${pathName}`)); | ||
route.aliases.push(createAliasedRoute(`${action}.get`, `GET ${pathName}/:id`)); | ||
route.aliases.push(createAliasedRoute(`${action}.create`, `POST ${pathName}`)); | ||
route.aliases.push(createAliasedRoute(`${action}.update`, `PUT ${pathName}/:id`)); | ||
route.aliases.push(createAliasedRoute(`${action}.remove`, `DELETE ${pathName}/:id`)); | ||
route.aliases.push({ | ||
action, | ||
method, | ||
re, | ||
match: url => { | ||
const m = re.exec(url); | ||
if (!m) return false; | ||
const params = {}; | ||
let key, param; | ||
for (let i = 0; i < keys.length; i++) { | ||
key = keys[i]; | ||
param = m[i + 1]; | ||
if (!param) continue; | ||
params[key.name] = decodeParam(param); | ||
if (key.repeat) | ||
params[key.name] = params[key.name].split(key.delimiter); | ||
} | ||
return params; | ||
} | ||
}); | ||
} else { | ||
route.aliases.push(createAliasedRoute(action, matchPath)); | ||
} | ||
}); | ||
@@ -196,0 +213,0 @@ } |
@@ -686,2 +686,96 @@ "use strict"; | ||
describe("Test REST shorthand aliases", () => { | ||
let broker; | ||
let service; | ||
let server; | ||
beforeAll(() => { | ||
[ broker, service, server] = setup({ | ||
routes: [{ | ||
path: "/api", | ||
aliases: { | ||
"REST posts": "posts" | ||
} | ||
}] | ||
}); | ||
broker.loadService("./test/services/posts.service"); | ||
}); | ||
it("GET /api/posts", () => { | ||
return request(server) | ||
.get("/api/posts") | ||
.expect(200) | ||
.expect("Content-Type", "application/json") | ||
.then(res => { | ||
expect(res.body.length).toBe(5); | ||
}); | ||
}); | ||
it("GET /api/posts/2", () => { | ||
return request(server) | ||
.get("/api/posts/2") | ||
.expect(200) | ||
.expect("Content-Type", "application/json") | ||
.then(res => { | ||
expect(res.body).toBeInstanceOf(Object); | ||
expect(res.body.title).toBeDefined(); | ||
expect(res.body.id).toBe(2); | ||
}); | ||
}); | ||
it("POST /api/posts", () => { | ||
return request(server) | ||
.post("/api/posts") | ||
.send({ id: 8, title: "Test", content: "Content" }) | ||
.expect(200) | ||
.expect("Content-Type", "application/json") | ||
.then(res => { | ||
expect(res.body.id).toBe(8); | ||
expect(res.body.title).toBe("Test"); | ||
expect(res.body.content).toBe("Content"); | ||
}); | ||
}); | ||
it("PUT /api/posts/8", () => { | ||
return request(server) | ||
.put("/api/posts/8") | ||
.send({ title: "Modified" }) | ||
.expect(200) | ||
.expect("Content-Type", "application/json") | ||
.then(res => { | ||
expect(res.body.id).toBe(8); | ||
expect(res.body.title).toBe("Modified"); | ||
expect(res.body.content).toBe("Content"); | ||
}); | ||
}); | ||
it("GET /api/posts/8", () => { | ||
return request(server) | ||
.get("/api/posts/8") | ||
.expect(200) | ||
.expect("Content-Type", "application/json") | ||
.then(res => { | ||
expect(res.body.id).toBe(8); | ||
expect(res.body.title).toBe("Modified"); | ||
expect(res.body.content).toBe("Content"); | ||
}); | ||
}); | ||
it("DELETE /api/posts/8", () => { | ||
return request(server) | ||
.delete("/api/posts/8") | ||
.expect(200); | ||
}); | ||
it("GET /api/posts/8", () => { | ||
return request(server) | ||
.get("/api/posts/8") | ||
.expect(404); | ||
}); | ||
}); | ||
describe("Test alias & whitelist", () => { | ||
@@ -688,0 +782,0 @@ let broker; |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
748309
40
2898