http://jasonwatmore.com/post/2017/12/15/angular-5-mock-backend-example-for-backendless-development をベースにしたFakeBackendsModuleのサンプル。 FakeBackendInterceptorBaseを継承して各APIの処理を書くことで、共通部分をまとめています。
Last active
March 23, 2018 09:36
-
-
Save TakuyaAbe/660b9376e77d278d49e49d168ea80b60 to your computer and use it in GitHub Desktop.
fake-backend module based on angular-5-mock-backend-example-for-backendless-development
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// http://jasonwatmore.com/post/2017/12/15/angular-5-mock-backend-example-for-backendless-development | |
import { Injectable } from '@angular/core'; | |
import { HttpRequest, HTTP_INTERCEPTORS } from '@angular/common/http'; | |
import { FakeBackendInterceptorBase } from 'src/app/fake-backends/fake-backend-base'; | |
import { LoggerService } from 'src/libs/logger/src/logger.module'; | |
const LOGIN_PATH = '/cmn/auth/login'; | |
const LOGOUT_PATH = '/cmn/auth/logout'; | |
@Injectable() | |
export class FakeBackendAuth extends FakeBackendInterceptorBase { | |
constructor(protected logger: LoggerService) { | |
super(logger); | |
} | |
responseBodyBulider(request: HttpRequest<any>) { | |
const loginResBody = { | |
accessToken: 'dummyAccessToken', | |
refreshToken: 'dummyRefreshToken', | |
userId: 'xxx', | |
parentUserId: 'xxx', | |
language: 'xxx', | |
username: 'xxx', | |
}; | |
const DUMMY_PASSWORD = 'xxx'; | |
const DUMMY_userId = 'yyy'; | |
if (request.url.endsWith(LOGIN_PATH) && request.method === 'POST') { | |
if (request.body.userId === DUMMY_userId && request.body.password === DUMMY_PASSWORD) { | |
// if login details are valid return 200 OK with user details and fake jwt token | |
const body = loginResBody; | |
this.logger.info(`FAKE RES of ${request.url}`, body); | |
return { status: 200, body: body }; | |
} else { | |
// else return 400 bad request | |
return { status: 400, body: 'invalid auth info' }; | |
} | |
} | |
// logout | |
if (request.url.endsWith(LOGOUT_PATH) && request.method === 'POST') { | |
// check for fake auth token in header and return user if valid, this security is implemented server side in a real application | |
if (request.headers.get('Authorization') === 'Bearer fake-jwt-token') { | |
return { status: 200, body: true }; | |
} else { | |
// return 401 not authorised if token is null or invalid | |
return { status: 200, body: false }; | |
} | |
} | |
} | |
} | |
export let cmnAuthFakeBackendProvider = { | |
// use fake backend in place of Http service for backend-less development | |
provide: HTTP_INTERCEPTORS, | |
useClass: FakeBackendAuth, | |
multi: true | |
}; |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// http://jasonwatmore.com/post/2017/12/15/angular-5-mock-backend-example-for-backendless-development | |
import { Injectable } from '@angular/core'; | |
import { HttpRequest, HTTP_INTERCEPTORS } from '@angular/common/http'; | |
import { LoggerService } from 'src/libs/logger/src/logger.module'; | |
import { FakeBackendInterceptorBase } from 'src/app/fake-backends/fake-backend-base'; | |
import { getApiPathFromId } from 'src/app/utils/utils'; | |
@Injectable() | |
export class FakeBackendInterceptor extends FakeBackendInterceptorBase { | |
API_ID = ['DUMMY-S3']; | |
PATH = this.API_ID.map(id => getApiPathFromId(id)); | |
constructor(protected logger: LoggerService) { | |
super(logger); | |
} | |
responseBodyBulider(request: HttpRequest<any>) { | |
if (this.PATH.some(path => request.url.endsWith(path)) && request.method === 'HEAD') { | |
if (Math.random() > 0.9) { | |
return { | |
status: 200, // 1/10の確率でファイルができたことにするレスポンスをかえす | |
body: '', | |
url: this.PATH[0] // ポーリング処理は返り値のURLをそのまま利用するため、urlふくめたダミーレスポンスにする | |
}; | |
} | |
} else if (this.PATH.some(path => request.url.endsWith(path)) && request.method === 'GET') { | |
// 実際のファイルダウンロード。こちらはfack-backendsではつくらない。 | |
} | |
} | |
} | |
export let DUMMY_S3FakeBackendProvider = { | |
// use fake backend in place of Http service for backend-less development | |
provide: HTTP_INTERCEPTORS, | |
useClass: FakeBackendInterceptor, | |
multi: true | |
}; |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// http://jasonwatmore.com/post/2017/12/15/angular-5-mock-backend-example-for-backendless-development | |
import { Injectable } from '@angular/core'; | |
import { HttpRequest, HttpResponse, HttpHandler, HttpInterceptor, HttpHeaders } from '@angular/common/http'; | |
import { Observable } from 'rxjs/Observable'; | |
import { LoggerService } from 'src/libs/logger/src/logger.module'; | |
export interface DummyResponse { | |
status: number; | |
body: any; | |
url?: string; | |
} | |
@Injectable() | |
export abstract class FakeBackendInterceptorBase implements HttpInterceptor { | |
PATH: string | string[]; | |
API_ID: string | string[]; | |
constructor(protected logger: LoggerService) {} | |
intercept(request: HttpRequest<any>, next: HttpHandler) { | |
// wrap in delayed observable to simulate server api call | |
return ( | |
Observable.of(null) | |
.mergeMap(() => { | |
const res = this.responseBodyBulider(request); | |
if (res) { | |
return this.interceptHandler(res, request); | |
} else { | |
// pass through any requests not handled above | |
return next.handle(request); | |
} | |
}) | |
// call materialize and dematerialize to ensure delay even if an error is thrown | |
// (https://github.com/Reactive-Extensions/RxJS/issues/648) | |
.materialize() | |
.delay(50) | |
.dematerialize() | |
); | |
} | |
abstract responseBodyBulider(request: HttpRequest<any>): DummyResponse | null; | |
interceptHandler(res: DummyResponse, request: HttpRequest<any>) { | |
const headers = new HttpHeaders({ | |
'Content-Type': 'application/json; charset=utf-8', | |
'WWW-Authenticate': ':Bearer dummyToken' | |
}); | |
if (request.method === 'GET') { | |
headers.append('ETag', '201711122209010'); | |
} | |
const fakeRes = new HttpResponse({ | |
status: res.status, | |
body: res.body, | |
url: res.url ? res.url : null, | |
headers: headers | |
}); | |
this.logger.info('FakeBackend', 'fake response returned', fakeRes); | |
return Observable.of(fakeRes); | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import { NgModule, ModuleWithProviders } from '@angular/core'; | |
import { CommonModule } from '@angular/common'; | |
import { cmnAuthFakeBackendProvider } from './auth'; | |
import { DUMMY_S3FakeBackendProvider } from './DUMMY-S3'; | |
@NgModule({ | |
imports: [CommonModule], | |
declarations: [] | |
}) | |
export class FakeBackendsModule { | |
static forRoot(): ModuleWithProviders { | |
return { | |
ngModule: FakeBackendsModule, | |
providers: [ | |
DUMMY_S3FakeBackendProvider, | |
cmnAuthFakeBackendProvider, | |
] | |
}; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment