From 3060e203cc0b39b2400aec57417f920fddebf9a6 Mon Sep 17 00:00:00 2001 From: Ward Bell Date: Sun, 9 Oct 2016 17:37:12 -0700 Subject: [PATCH] feature: for v.1.0.6 enable parseUrl override and show how to use overrides --- .gitignore | 4 + .npmignore | 1 + CHANGELOG.md | 11 ++ README.md | 29 +++++ examples/hero-data.service.ts | 131 +++++++++++++++++++ in-memory-backend.service.d.ts | 59 ++++++--- in-memory-backend.service.js | 126 ++++++++++-------- in-memory-backend.service.js.map | 2 +- in-memory-backend.service.metadata.json | 2 +- package.json | 3 +- src/in-memory-backend.service.ts | 166 +++++++++++++++--------- 11 files changed, 396 insertions(+), 138 deletions(-) create mode 100644 examples/hero-data.service.ts diff --git a/.gitignore b/.gitignore index 153df7b..69b054a 100644 --- a/.gitignore +++ b/.gitignore @@ -6,3 +6,7 @@ src/*.d.ts src/*.js src/*.js.map src/*.metadata.json +examples/*.d.ts +examples/*.js +examples/*.js.map +examples/*.metadata.json diff --git a/.npmignore b/.npmignore index 279b96d..f03c076 100644 --- a/.npmignore +++ b/.npmignore @@ -1,4 +1,5 @@ aot +examples in-memory-web-api src gulpfile.js diff --git a/CHANGELOG.md b/CHANGELOG.md index 8925a08..f1ecda7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,4 +1,15 @@ # "angular-in-memory-web-api" versions + +## 0.1.6 (2016-10-09) +* Do not add delay to observable if delay value === 0 (issue #47) +* Can override `parseUrl` method in your db service class (issue #46, #35) +* README.md explains `parseUrl` override. +* Exports functions helpful for custom HTTP Method Interceptors + * `createErrorResponse` + * `createObservableResponse` + * `setStatusText` +* Added `examples/hero-data.service.ts` to show overrides (issue #44) + ## 0.1.5 (2016-10-03) * project.json license changed again to match angular.io package.json diff --git a/README.md b/README.md index 5185e9d..c58c41e 100644 --- a/README.md +++ b/README.md @@ -104,6 +104,16 @@ If an existing, running remote server should handle requests for collections that are not in the in-memory database, set `Config.passThruUnknownUrl: true`. This service will forward unrecognized requests via a base version of the Angular XHRBackend. +## _parseUrl_ override + +The `parseUrl` method breaks down the request URL into a `ParsedUrl` object. +`ParsedUrl` is a public interface whose properties guide the in-memory web api +as it processes the request. + +Request URLs for your api may not match the api imagined by the default `parseUrl` and may even cause it to throw an error. +You can override the default by implementing a `parseUrl` method in your `InMemoryDbService`. +Such a method must take the incoming request URL string and return a `ParsedUrl` object. + ## HTTP method interceptors If you make requests this service can't handle but still want an in-memory database to hold values, @@ -123,6 +133,25 @@ db: Object; // the current in-mem database collections config: InMemoryBackendConfigArgs; // the current config passThruBackend: ConnectionBackend; // pass through backend, if it exists ``` +## Examples + +The file `examples/hero-data.service.ts` is an example of a Hero-oriented `InMemoryDbService`, +derived from the [HTTP Client](https://angular.io/docs/ts/latest/guide/server-communication.html) +sample in the Angular documentation. + +Add the following line to `AppModule.imports` +``` +InMemoryWebApiModule.forRoot(HeroDataService) +``` + +That file also has a `HeroDataOverrideService` derived class that demonstrates overriding +the `parseUrl` method and an HTTP GET interceptor. + +Add the following line to `AppModule.imports` to see it in action: +``` +InMemoryWebApiModule.forRoot(HeroDataOverrideService) +``` + # To Do * add tests (shameful omission!) diff --git a/examples/hero-data.service.ts b/examples/hero-data.service.ts new file mode 100644 index 0000000..c2054db --- /dev/null +++ b/examples/hero-data.service.ts @@ -0,0 +1,131 @@ +/** + * This is an example of a Hero-oriented InMemoryDbService. + * + * Add the following line to `AppModule.imports` + * InMemoryWebApiModule.forRoot(HeroDataService) // or HeroDataOverrideService + */ +import { + InMemoryDbService, + createErrorResponse, createObservableResponse, HttpMethodInterceptorArgs, ParsedUrl, STATUS +} from 'angular-in-memory-web-api'; + +import { ResponseOptions, URLSearchParams } from '@angular/http'; + +// For AoT compile +/* tslint:disable:no-unused-variable */ +import { Observable } from 'rxjs/Observable'; +import { Response } from '@angular/http'; +/* tslint:enable:no-unused-variable */ + +export class HeroDataService implements InMemoryDbService { + createDb() { + let heroes = [ + { id: '1', name: 'Windstorm' }, + { id: '2', name: 'Bombasto' }, + { id: '3', name: 'Magneta' }, + { id: '4', name: 'Tornado' } + ]; + return {heroes}; + } +} + +/** + * This is an example of a Hero-oriented InMemoryDbService with method overrides. + */ +export class HeroDataOverrideService extends HeroDataService { + // parseUrl override + parseUrl(url: string): ParsedUrl { + try { + const loc = this.getLocation(url); + let drop = 0; + let urlRoot = ''; + if (loc.host !== undefined) { + // url for a server on a different host! + // assume it's collection is actually here too. + drop = 1; // the leading slash + urlRoot = loc.protocol + '//' + loc.host + '/'; + } + const path = loc.pathname.substring(drop); + let [base, collectionName, id] = path.split('/'); + const resourceUrl = urlRoot + base + '/' + collectionName + '/'; + [collectionName] = collectionName.split('.'); // ignore anything after the '.', e.g., '.json' + const query = loc.search && new URLSearchParams(loc.search.substr(1)); + + const result = { base, collectionName, id, query, resourceUrl }; + console.log('override parseUrl:'); + console.log(result); + return result; + } catch (err) { + const msg = `unable to parse url '${url}'; original error: ${err.message}`; + throw new Error(msg); + } + } + + // HTTP GET interceptor + protected get(interceptorArgs: HttpMethodInterceptorArgs) { + + console.log('HTTP GET override'); + let resp: ResponseOptions; + + const {id, query, collection, collectionName, headers} = interceptorArgs.requestInfo; + let data = collection; + + if (id) { + data = this.findById(collection, id); + } else if (query) { + data = this.applyQuery(collection, query); + } + + if (data) { + resp = new ResponseOptions({ + body: { data: this.clone(data) }, + headers: headers, + status: STATUS.OK + }); + } else { + resp = createErrorResponse(STATUS.NOT_FOUND, + `'${collectionName}' with id='${id}' not found`); + } + + return createObservableResponse(resp); + } + + /////////// private /////////////// + private applyQuery(collection: any[], query: URLSearchParams) { + // extract filtering conditions - {propertyName, RegExps) - from query/search parameters + const conditions: {name: string, rx: RegExp}[] = []; + const caseSensitive = 'i'; + query.paramsMap.forEach((value: string[], name: string) => { + value.forEach(v => conditions.push({name, rx: new RegExp(decodeURI(v), caseSensitive)})); + }); + + const len = conditions.length; + if (!len) { return collection; } + + // AND the RegExp conditions + return collection.filter(row => { + let ok = true; + let i = len; + while (ok && i) { + i -= 1; + const cond = conditions[i]; + ok = cond.rx.test(row[cond.name]); + } + return ok; + }); + } + + private clone(data: any) { + return JSON.parse(JSON.stringify(data)); + } + + private findById(collection: any[], id: number | string) { + return collection.find((item: any) => item.id === id); + } + + private getLocation(href: string) { + const l = document.createElement('a'); + l.href = href; + return l; + }; +} diff --git a/in-memory-backend.service.d.ts b/in-memory-backend.service.d.ts index 9eac2d0..92b5278 100644 --- a/in-memory-backend.service.d.ts +++ b/in-memory-backend.service.d.ts @@ -2,6 +2,23 @@ import { Injector } from '@angular/core'; import { Connection, ConnectionBackend, Headers, Request, Response, ResponseOptions, URLSearchParams } from '@angular/http'; import { Observable } from 'rxjs/Observable'; import 'rxjs/add/operator/delay'; +/** + * Create an error Response from an HTTP status code and error message + */ +export declare function createErrorResponse(status: number, message: string): ResponseOptions; +/** + * Create an Observable response from response options: + */ +export declare function createObservableResponse(resOptions: ResponseOptions): Observable; +/** +* Interface for object passed to an HTTP method override method +*/ +export interface HttpMethodInterceptorArgs { + requestInfo: RequestInfo; + db: Object; + config: InMemoryBackendConfigArgs; + passThruBackend: ConnectionBackend; +} /** * Interface for a class that creates an in-memory database * @@ -68,6 +85,10 @@ export interface InMemoryBackendConfigArgs { export declare class InMemoryBackendConfig implements InMemoryBackendConfigArgs { constructor(config?: InMemoryBackendConfigArgs); } +/** + * Returns true if the the Http Status Code is 200-299 (success) + */ +export declare function isSuccess(status: number): boolean; /** * Interface for object w/ info about the current request url * extracted from an Http Request @@ -83,15 +104,26 @@ export interface RequestInfo { resourceUrl: string; } /** -* Interface for object passed to an HTTP method override method -*/ -export interface HttpMethodInterceptorArgs { - requestInfo: RequestInfo; - db: Object; - config: InMemoryBackendConfigArgs; - passThruBackend: ConnectionBackend; + * Set the status text in a response: + */ +export declare function setStatusText(options: ResponseOptions): ResponseOptions; +/** + * + * Interface for the result of the parseUrl method: + * Given URL "http://localhost:8080/api/characters/42?foo=1 the default implementation returns + * base: 'api' + * collectionName: 'characters' + * id: '42' + * query: new URLSearchParams('foo=1') + * resourceUrl: 'api/characters/42?foo=1' + */ +export interface ParsedUrl { + base: string; + collectionName: string; + id: string; + query: URLSearchParams; + resourceUrl: string; } -export declare const isSuccess: (status: number) => boolean; /** * Simulate the behavior of a RESTy web api * backed by the simple in-memory data store provided by the injected InMemoryDataService service. @@ -172,8 +204,6 @@ export declare class InMemoryBackendService { * http.post('commands/config', '{"delay":1000}'); */ protected commands(reqInfo: RequestInfo): Observable; - protected createErrorResponse(status: number, message: string): ResponseOptions; - protected createObservableResponse(resOptions: ResponseOptions): Observable; protected delete({id, collection, collectionName, headers}: RequestInfo): ResponseOptions; protected findById(collection: any[], id: number | string): any; protected genId(collection: any): any; @@ -183,13 +213,7 @@ export declare class InMemoryBackendService { protected parseId(collection: { id: any; }[], id: string): any; - protected parseUrl(url: string): { - base: string; - id: string; - collectionName: string; - resourceUrl: string; - query: URLSearchParams; - }; + protected parseUrl(url: string): ParsedUrl; protected post({collection, headers, id, req, resourceUrl}: RequestInfo): ResponseOptions; protected put({id, collection, collectionName, headers, req}: RequestInfo): ResponseOptions; protected removeById(collection: any[], id: number): boolean; @@ -198,5 +222,4 @@ export declare class InMemoryBackendService { */ protected resetDb(): void; protected setPassThruBackend(): void; - protected setStatusText(options: ResponseOptions): ResponseOptions; } diff --git a/in-memory-backend.service.js b/in-memory-backend.service.js index 9a5313c..4b4e4bd 100644 --- a/in-memory-backend.service.js +++ b/in-memory-backend.service.js @@ -4,6 +4,36 @@ var http_1 = require('@angular/http'); var Observable_1 = require('rxjs/Observable'); require('rxjs/add/operator/delay'); var http_status_codes_1 = require('./http-status-codes'); +//////////// HELPERS /////////// +/** + * Create an error Response from an HTTP status code and error message + */ +function createErrorResponse(status, message) { + return new http_1.ResponseOptions({ + body: { 'error': "" + message }, + headers: new http_1.Headers({ 'Content-Type': 'application/json' }), + status: status + }); +} +exports.createErrorResponse = createErrorResponse; +/** + * Create an Observable response from response options: + */ +function createObservableResponse(resOptions) { + resOptions = setStatusText(resOptions); + var res = new http_1.Response(resOptions); + return new Observable_1.Observable(function (responseObserver) { + if (isSuccess(res.status)) { + responseObserver.next(res); + responseObserver.complete(); + } + else { + responseObserver.error(res); + } + return function () { }; // unsubscribe function + }); +} +exports.createObservableResponse = createObservableResponse; /** * Interface for a class that creates an in-memory database * @@ -45,7 +75,30 @@ var InMemoryBackendConfig = (function () { return InMemoryBackendConfig; }()); exports.InMemoryBackendConfig = InMemoryBackendConfig; -exports.isSuccess = function (status) { return (status >= 200 && status < 300); }; +/** + * Returns true if the the Http Status Code is 200-299 (success) + */ +function isSuccess(status) { return status >= 200 && status < 300; } +exports.isSuccess = isSuccess; +; +/** + * Set the status text in a response: + */ +function setStatusText(options) { + try { + var statusCode = http_status_codes_1.STATUS_CODE_INFO[options.status]; + options['statusText'] = statusCode ? statusCode.text : 'Unknown Status'; + return options; + } + catch (err) { + return new http_1.ResponseOptions({ + status: http_status_codes_1.STATUS.INTERNAL_SERVER_ERROR, + statusText: 'Invalid Server Operation' + }); + } +} +exports.setStatusText = setStatusText; +//////////// InMemoryBackendService /////////// /** * Simulate the behavior of a RESTy web api * backed by the simple in-memory data store provided by the injected InMemoryDataService service. @@ -118,7 +171,12 @@ var InMemoryBackendService = (function () { * which must return an `Observable` */ InMemoryBackendService.prototype.handleRequest = function (req) { - var _a = this.parseUrl(req.url), base = _a.base, collectionName = _a.collectionName, id = _a.id, resourceUrl = _a.resourceUrl, query = _a.query; + var parsed = this.inMemDbService['parseUrl'] ? + // parse with override method + this.inMemDbService['parseUrl'](req.url) : + // parse with default url parser + this.parseUrl(req.url); + var base = parsed.base, collectionName = parsed.collectionName, id = parsed.id, query = parsed.query, resourceUrl = parsed.resourceUrl; var collection = this.db[collectionName]; var reqInfo = { req: req, @@ -156,14 +214,14 @@ var InMemoryBackendService = (function () { return this.passThruBackend.createConnection(req).response; } else { - resOptions = this.createErrorResponse(http_status_codes_1.STATUS.NOT_FOUND, "Collection '" + collectionName + "' not found"); - return this.createObservableResponse(resOptions); + resOptions = createErrorResponse(http_status_codes_1.STATUS.NOT_FOUND, "Collection '" + collectionName + "' not found"); + return createObservableResponse(resOptions); } } catch (error) { var err = error.message || error; - resOptions = this.createErrorResponse(http_status_codes_1.STATUS.INTERNAL_SERVER_ERROR, "" + err); - return this.createObservableResponse(resOptions); + resOptions = createErrorResponse(http_status_codes_1.STATUS.INTERNAL_SERVER_ERROR, "" + err); + return createObservableResponse(resOptions); } }; /** @@ -214,10 +272,10 @@ var InMemoryBackendService = (function () { resOptions = this.delete(reqInfo); break; default: - resOptions = this.createErrorResponse(http_status_codes_1.STATUS.METHOD_NOT_ALLOWED, 'Method not allowed'); + resOptions = createErrorResponse(http_status_codes_1.STATUS.METHOD_NOT_ALLOWED, 'Method not allowed'); break; } - return this.createObservableResponse(resOptions); + return createObservableResponse(resOptions); }; /** * When the `base`="commands", the `collectionName` is the command @@ -256,39 +314,14 @@ var InMemoryBackendService = (function () { } break; default: - resOptions = this.createErrorResponse(http_status_codes_1.STATUS.INTERNAL_SERVER_ERROR, "Unknown command \"" + command + "\""); + resOptions = createErrorResponse(http_status_codes_1.STATUS.INTERNAL_SERVER_ERROR, "Unknown command \"" + command + "\""); } - return this.createObservableResponse(resOptions); - }; - InMemoryBackendService.prototype.createErrorResponse = function (status, message) { - return new http_1.ResponseOptions({ - body: { 'error': "" + message }, - headers: new http_1.Headers({ 'Content-Type': 'application/json' }), - status: status - }); - }; - InMemoryBackendService.prototype.createObservableResponse = function (resOptions) { - resOptions = this.setStatusText(resOptions); - if (this.config.defaultResponseOptions) { - resOptions = this.config.defaultResponseOptions.merge(resOptions); - } - var res = new http_1.Response(resOptions); - return new Observable_1.Observable(function (responseObserver) { - if (exports.isSuccess(res.status)) { - responseObserver.next(res); - responseObserver.complete(); - } - else { - responseObserver.error(res); - } - return function () { }; // unsubscribe function - }) - .delay(this.config.delay || 500); + return createObservableResponse(resOptions); }; InMemoryBackendService.prototype.delete = function (_a) { var id = _a.id, collection = _a.collection, collectionName = _a.collectionName, headers = _a.headers; if (!id) { - return this.createErrorResponse(http_status_codes_1.STATUS.NOT_FOUND, "Missing \"" + collectionName + "\" id"); + return createErrorResponse(http_status_codes_1.STATUS.NOT_FOUND, "Missing \"" + collectionName + "\" id"); } var exists = this.removeById(collection, id); return new http_1.ResponseOptions({ @@ -317,7 +350,7 @@ var InMemoryBackendService = (function () { data = this.applyQuery(collection, query); } if (!data) { - return this.createErrorResponse(http_status_codes_1.STATUS.NOT_FOUND, "'" + collectionName + "' with id='" + id + "' not found"); + return createErrorResponse(http_status_codes_1.STATUS.NOT_FOUND, "'" + collectionName + "' with id='" + id + "' not found"); } return new http_1.ResponseOptions({ body: { data: this.clone(data) }, @@ -363,7 +396,7 @@ var InMemoryBackendService = (function () { var resourceUrl = urlRoot + base + '/' + collectionName + '/'; collectionName = collectionName.split('.')[0]; // ignore anything after the '.', e.g., '.json' var query = loc.search && new http_1.URLSearchParams(loc.search.substr(1)); - return { base: base, id: id, collectionName: collectionName, resourceUrl: resourceUrl, query: query }; + return { base: base, collectionName: collectionName, id: id, query: query, resourceUrl: resourceUrl }; } catch (err) { var msg = "unable to parse url '" + url + "'; original error: " + err.message; @@ -401,10 +434,10 @@ var InMemoryBackendService = (function () { var id = _a.id, collection = _a.collection, collectionName = _a.collectionName, headers = _a.headers, req = _a.req; var item = JSON.parse(req.text()); if (!id) { - return this.createErrorResponse(http_status_codes_1.STATUS.NOT_FOUND, "Missing '" + collectionName + "' id"); + return createErrorResponse(http_status_codes_1.STATUS.NOT_FOUND, "Missing '" + collectionName + "' id"); } if (id !== item.id) { - return this.createErrorResponse(http_status_codes_1.STATUS.BAD_REQUEST, "\"" + collectionName + "\" id does not match item.id"); + return createErrorResponse(http_status_codes_1.STATUS.BAD_REQUEST, "\"" + collectionName + "\" id does not match item.id"); } var existingIx = this.indexOf(collection, id); if (existingIx > -1) { @@ -453,19 +486,6 @@ var InMemoryBackendService = (function () { } } }; - InMemoryBackendService.prototype.setStatusText = function (options) { - try { - var statusCode = http_status_codes_1.STATUS_CODE_INFO[options.status]; - options['statusText'] = statusCode ? statusCode.text : 'Unknown Status'; - return options; - } - catch (err) { - return new http_1.ResponseOptions({ - status: http_status_codes_1.STATUS.INTERNAL_SERVER_ERROR, - statusText: 'Invalid Server Operation' - }); - } - }; /** @nocollapse */ InMemoryBackendService.ctorParameters = [ { type: core_1.Injector, }, diff --git a/in-memory-backend.service.js.map b/in-memory-backend.service.js.map index cfcf51b..a0dd749 100644 --- a/in-memory-backend.service.js.map +++ b/in-memory-backend.service.js.map @@ -1 +1 @@ -{"version":3,"file":"in-memory-backend.service.js","sourceRoot":"C:/github/angular.in-memory-web-api/src/","sources":["src/in-memory-backend.service.ts"],"names":[],"mappings":"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"} \ No newline at end of file +{"version":3,"file":"in-memory-backend.service.js","sourceRoot":"C:/github/angular.in-memory-web-api/src/","sources":["src/in-memory-backend.service.ts"],"names":[],"mappings":"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"} \ No newline at end of file diff --git a/in-memory-backend.service.metadata.json b/in-memory-backend.service.metadata.json index b1a19ac..64f98ee 100644 --- a/in-memory-backend.service.metadata.json +++ b/in-memory-backend.service.metadata.json @@ -1 +1 @@ -{"__symbolic":"module","version":1,"metadata":{"isSuccess":{"__symbolic":"error","message":"Function call not supported","line":116,"character":25}}} \ No newline at end of file +{"__symbolic":"module","version":1,"metadata":{"createErrorResponse":{"__symbolic":"function","parameters":["status","message"],"value":{"__symbolic":"error","message":"Expression form not supported","line":20,"character":21}},"isSuccess":{"__symbolic":"function","parameters":["status"],"value":{"__symbolic":"binop","operator":"&&","left":{"__symbolic":"binop","operator":">=","left":{"__symbolic":"reference","name":"status"},"right":200},"right":{"__symbolic":"binop","operator":"<","left":{"__symbolic":"reference","name":"status"},"right":300}}}}} \ No newline at end of file diff --git a/package.json b/package.json index 706c395..423b495 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "angular-in-memory-web-api", - "version": "0.1.5", + "version": "0.1.6", "description": "An in-memory web api for Angular demos and tests", "main":"index.js", "jsnext:main": "esm/index.js", @@ -51,6 +51,7 @@ "rxjs": "5.0.0-beta.12", "zone.js": "^0.6.25", + "angular-in-memory-web-api": "~0.1.6", "concurrently": "^3.0.0", "core-js": "^2.4.1", "lite-server": "^2.2.2", diff --git a/src/in-memory-backend.service.ts b/src/in-memory-backend.service.ts index 5a305fb..ab5633a 100644 --- a/src/in-memory-backend.service.ts +++ b/src/in-memory-backend.service.ts @@ -1,14 +1,58 @@ import { Inject, Injector, Optional } from '@angular/core'; + import { BaseResponseOptions, BrowserXhr, Connection, ConnectionBackend, Headers, ReadyState, Request, RequestMethod, Response, ResponseOptions, URLSearchParams, XHRBackend, XSRFStrategy } from '@angular/http'; + import { Observable } from 'rxjs/Observable'; import { Observer } from 'rxjs/Observer'; import 'rxjs/add/operator/delay'; import { STATUS, STATUS_CODE_INFO } from './http-status-codes'; +//////////// HELPERS /////////// + +/** + * Create an error Response from an HTTP status code and error message + */ +export function createErrorResponse(status: number, message: string) { + return new ResponseOptions({ + body: { 'error': `${message}` }, + headers: new Headers({ 'Content-Type': 'application/json' }), + status: status + }); +} + +/** + * Create an Observable response from response options: + */ +export function createObservableResponse(resOptions: ResponseOptions): Observable { + resOptions = setStatusText(resOptions); + + const res = new Response(resOptions); + + return new Observable((responseObserver: Observer) => { + if (isSuccess(res.status)) { + responseObserver.next(res); + responseObserver.complete(); + } else { + responseObserver.error(res); + } + return () => { }; // unsubscribe function + }); +} + +/** +* Interface for object passed to an HTTP method override method +*/ +export interface HttpMethodInterceptorArgs { + requestInfo: RequestInfo; // parsed request + db: Object; // the current in-mem database collections + config: InMemoryBackendConfigArgs; // the current config + passThruBackend: ConnectionBackend; // pass through backend, if it exists +} + /** * Interface for a class that creates an in-memory database * @@ -89,6 +133,11 @@ export class InMemoryBackendConfig implements InMemoryBackendConfigArgs { } } +/** + * Returns true if the the Http Status Code is 200-299 (success) + */ +export function isSuccess(status: number): boolean { return status >= 200 && status < 300; }; + /** * Interface for object w/ info about the current request url * extracted from an Http Request @@ -105,17 +154,40 @@ export interface RequestInfo { } /** -* Interface for object passed to an HTTP method override method -*/ -export interface HttpMethodInterceptorArgs { - requestInfo: RequestInfo; // parsed request - db: Object; // the current in-mem database collections - config: InMemoryBackendConfigArgs; // the current config - passThruBackend: ConnectionBackend; // pass through backend, if it exists + * Set the status text in a response: + */ +export function setStatusText(options: ResponseOptions) { + try { + const statusCode = STATUS_CODE_INFO[options.status]; + options['statusText'] = statusCode ? statusCode.text : 'Unknown Status'; + return options; + } catch (err) { + return new ResponseOptions({ + status: STATUS.INTERNAL_SERVER_ERROR, + statusText: 'Invalid Server Operation' + }); + } } -export const isSuccess = (status: number): boolean => (status >= 200 && status < 300); +/** + * + * Interface for the result of the parseUrl method: + * Given URL "http://localhost:8080/api/characters/42?foo=1 the default implementation returns + * base: 'api' + * collectionName: 'characters' + * id: '42' + * query: new URLSearchParams('foo=1') + * resourceUrl: 'api/characters/42?foo=1' + */ +export interface ParsedUrl { + base: string; // the "base" of the resource + collectionName: string; // the name of the collection of data items + id: string; // the id of the item in the collection + query: URLSearchParams; // the query as an Angular `Http` client request's URLSearchParams object + resourceUrl: string; // the effective URL for the resource +} +//////////// InMemoryBackendService /////////// /** * Simulate the behavior of a RESTy web api * backed by the simple in-memory data store provided by the injected InMemoryDataService service. @@ -143,7 +215,6 @@ export const isSuccess = (status: number): boolean => (status >= 200 && status < * export class AppModule { ... } * ``` */ - export class InMemoryBackendService { protected passThruBackend: ConnectionBackend; protected config: InMemoryBackendConfigArgs = new InMemoryBackendConfig(); @@ -200,7 +271,14 @@ export class InMemoryBackendService { * which must return an `Observable` */ protected handleRequest(req: Request): Observable { - const {base, collectionName, id, resourceUrl, query} = this.parseUrl(req.url); + + const parsed = this.inMemDbService['parseUrl'] ? + // parse with override method + this.inMemDbService['parseUrl'](req.url) as ParsedUrl : + // parse with default url parser + this.parseUrl(req.url); + + const { base, collectionName, id, query, resourceUrl } = parsed; const collection = this.db[collectionName]; const reqInfo: RequestInfo = { req: req, @@ -240,14 +318,14 @@ export class InMemoryBackendService { return this.passThruBackend.createConnection(req).response; } else { - resOptions = this.createErrorResponse(STATUS.NOT_FOUND, `Collection '${collectionName}' not found`); - return this.createObservableResponse(resOptions); + resOptions = createErrorResponse(STATUS.NOT_FOUND, `Collection '${collectionName}' not found`); + return createObservableResponse(resOptions); } } catch (error) { const err = error.message || error; - resOptions = this.createErrorResponse(STATUS.INTERNAL_SERVER_ERROR, `${err}`); - return this.createObservableResponse(resOptions); + resOptions = createErrorResponse(STATUS.INTERNAL_SERVER_ERROR, `${err}`); + return createObservableResponse(resOptions); } } @@ -303,10 +381,10 @@ export class InMemoryBackendService { resOptions = this.delete(reqInfo); break; default: - resOptions = this.createErrorResponse(STATUS.METHOD_NOT_ALLOWED, 'Method not allowed'); + resOptions = createErrorResponse(STATUS.METHOD_NOT_ALLOWED, 'Method not allowed'); break; } - return this.createObservableResponse(resOptions); + return createObservableResponse(resOptions); } /** @@ -346,43 +424,15 @@ export class InMemoryBackendService { } break; default: - resOptions = this.createErrorResponse( + resOptions = createErrorResponse( STATUS.INTERNAL_SERVER_ERROR, `Unknown command "${command}"`); } - return this.createObservableResponse(resOptions); - } - - protected createErrorResponse(status: number, message: string) { - return new ResponseOptions({ - body: { 'error': `${message}` }, - headers: new Headers({ 'Content-Type': 'application/json' }), - status: status - }); - } - - protected createObservableResponse(resOptions: ResponseOptions): Observable { - resOptions = this.setStatusText(resOptions); - if (this.config.defaultResponseOptions) { - resOptions = this.config.defaultResponseOptions.merge(resOptions); - } - - const res = new Response(resOptions); - - return new Observable((responseObserver: Observer) => { - if (isSuccess(res.status)) { - responseObserver.next(res); - responseObserver.complete(); - } else { - responseObserver.error(res); - } - return () => { }; // unsubscribe function - }) - .delay(this.config.delay || 500); + return createObservableResponse(resOptions); } protected delete({id, collection, collectionName, headers /*, req */}: RequestInfo) { if (!id) { - return this.createErrorResponse(STATUS.NOT_FOUND, `Missing "${collectionName}" id`); + return createErrorResponse(STATUS.NOT_FOUND, `Missing "${collectionName}" id`); } const exists = this.removeById(collection, id); return new ResponseOptions({ @@ -414,7 +464,7 @@ export class InMemoryBackendService { } if (!data) { - return this.createErrorResponse(STATUS.NOT_FOUND, + return createErrorResponse(STATUS.NOT_FOUND, `'${collectionName}' with id='${id}' not found`); } return new ResponseOptions({ @@ -446,7 +496,7 @@ export class InMemoryBackendService { return id; } - protected parseUrl(url: string) { + protected parseUrl(url: string): ParsedUrl { try { const loc = this.getLocation(url); let drop = this.config.rootPath.length; @@ -462,7 +512,7 @@ export class InMemoryBackendService { const resourceUrl = urlRoot + base + '/' + collectionName + '/'; [collectionName] = collectionName.split('.'); // ignore anything after the '.', e.g., '.json' const query = loc.search && new URLSearchParams(loc.search.substr(1)); - return { base, id, collectionName, resourceUrl, query }; + return { base, collectionName, id, query, resourceUrl }; } catch (err) { const msg = `unable to parse url '${url}'; original error: ${err.message}`; throw new Error(msg); @@ -498,10 +548,10 @@ export class InMemoryBackendService { protected put({id, collection, collectionName, headers, req}: RequestInfo) { const item = JSON.parse(req.text()); if (!id) { - return this.createErrorResponse(STATUS.NOT_FOUND, `Missing '${collectionName}' id`); + return createErrorResponse(STATUS.NOT_FOUND, `Missing '${collectionName}' id`); } if (id !== item.id) { - return this.createErrorResponse(STATUS.BAD_REQUEST, + return createErrorResponse(STATUS.BAD_REQUEST, `"${collectionName}" id does not match item.id`); } const existingIx = this.indexOf(collection, id); @@ -553,16 +603,4 @@ export class InMemoryBackendService { } } - protected setStatusText(options: ResponseOptions) { - try { - const statusCode = STATUS_CODE_INFO[options.status]; - options['statusText'] = statusCode ? statusCode.text : 'Unknown Status'; - return options; - } catch (err) { - return new ResponseOptions({ - status: STATUS.INTERNAL_SERVER_ERROR, - statusText: 'Invalid Server Operation' - }); - } - } }