注册模拟服务URL

时间:2017-09-02 22:35:20

标签: angular http http-mock

在Angular的快速入门示例的hero.service.ts文件step 7中,是这段代码:

@Injectable()
export class HeroService {

  private headers = new Headers({'Content-Type': 'application/json'});
  private heroesUrl = 'api/heroes';  // URL to web api

  constructor(private http: Http) { }

  getHeroes(): Promise<Hero[]> {
    return this.http.get(this.heroesUrl)
               .toPromise()
               .then(response => response.json().data as Hero[])
               .catch(this.handleError);
  }
}

我尝试将其翻译成我的应用程序:

@Injectable()
export class MyService {

  private headers = new Headers({'Content-Type': 'application/json'});
  private dataUrl = 'api/data';  // URL to web api

  constructor(private http: Http) { }

  getHeroes(): Promise<Hero[]> {
    return this.http.get(this.dataUrl) // <-- error here
               .toPromise()
               .then(response => response.json().data as MyData[])
               .catch(this.handleError);
  }
}

我在404 - Collection行上获得了not found个数据this.http.get,这完全可以理解,因为它只是一个随机路径。该端点没有API。

问题:Angular示例是如何工作的?它在哪里注册模拟HTTP请求的api/heroes路径?

1 个答案:

答案 0 :(得分:1)

使用Angular的常规HTTP模块时,命令:

return this.http.get(this.dataUrl)

期望this.dataUrl是包含真实HTTP Web服务地址的字符串。 (例如"http://swapi.co/api/people/1/"。)

在“常规使用”中,该命令将在this.dataUrl向HTTP服务发出请求。


但是......你的代码来自教程,它改变了一些东西。


如果您还记得,教程要求您将InMemoryWebApiModule添加到@NgModule

import { InMemoryWebApiModule } from 'angular-in-memory-web-api';
import { InMemoryDataService }  from './in-memory-data.service';
...

@NgModule({
  imports: [
    ...
    InMemoryWebApiModule.forRoot(InMemoryDataService),
    AppRoutingModule
  ],
  ...
})

您添加的那些行创建了一项服务,粗略地说,劫持您的http请求,阻止他们到达您提供的URL的真实服务器(比如myserver.com/api/heroes),而是将这些请求发送到虚假服务器

(有关详细信息,请注意InMemoryWebApiModule来自angular-in-memory-web-api。请检查https://github.com/angular/in-memory-web-api以了解其工作原理。)

现在,假的服务器必须返回一些有用的数据。它来自哪里?

这是InMemoryWebApiModule.forRoot(InMemoryDataService)的“第二部分”,即InMemoryDataService发挥作用。

来自Angular docs的演示通知InMemoryDataService定义了'./in-memory-data.service'

import { InMemoryDbService } from 'angular-in-memory-web-api';
export class InMemoryDataService implements InMemoryDbService {
  createDb() {
    const heroes = [
      { id: 0,  name: 'Zero' },
      ...
    ];
    return {heroes};
  }
}

现在,重要的部分是返回命令return {heroes};(如果您不熟悉语法,那是return {heroes: heroes};的缩写。

虚假服务器上的keys of that returned object define the available URLs

由于您要返回{heroes: <something>},因此网址api/heroes将在虚假服务器上提供。如果您返回{foo: <something>},则可以使用网址api/foo

如果您希望api/data可用,请返回{data: ...}之类的内容:

createDb() {
  const data = [
    { id: 0, name: 'AAAA' },
    { id: 1, name: 'BBBB' },
    ...
  ];
  return {data};
}

就是这样,这就是你需要改变的东西。

现在,请记住,对于生产(真正的)代码,您应该删除整个InMemoryWebApiModule.forRoot(InMemoryDataService)内容,并在this.dataUrl处回复真实的Web服务。< / p>