如何根据标头响应循环休息请求

时间:2019-02-19 10:22:33

标签: angular rest api

我正在从AZURE资源加载信息(总共有10个属性的3700条记录)。响应提供了一个标头(x-ms-continuation:{“ token”:“-RID:R-UdANZutGzxAwAAAAAAAA ==#RT:1#TRC:1000”,“ range”:{“ min”:“”,“ max “:” FF“}})表示要加载更多项,并且必须将标头添加到下一个请求,以便检索接下来的1000条记录。数据应存储在变量(帐户)中,因此在加载应用程序时,数据仅被提取一次。

在页面初始化上,该函数:public getAccounts()触发load()函数返回前1000条记录并将它们存储在帐户中。 在注释过的部分中,我尝试使用fetchAccounts来使其正常工作。

export class AccountsService {

    private accounts: AccountModel = null;

    constructor(private http: HttpClient) { }

/*     public getAccounts2() {
      console.log(this.accounts);
      return this.accounts;
    }

    loadAccounts() {
      this.fetchAccounts().subscribe(accounts => this.accounts.next(accounts));
    }

    public fetchAccounts(): Observable<AccountModel[]> {
      return this.http.get<AccountModel>(AZURE_URL + 'zuora/read', { headers })
        .pipe(
          expand(accounts => {
            if (!accounts) {
              console.log(accounts.headers.get('x-ms-continuation'));
              return EMPTY;
            }
            return this.http.get<AccountModel>(AZURE_URL + 'zuora/read', { headers });
          }),
          map(accounts => accounts.Documents),
          reduce((accData, data) => accData.concat(data), []),
        );
    } */

    public getAccounts(): AccountModel {
        return this.accounts;
    }

    load() {
        console.log('loading account data');
        return new Promise((resolve, reject) => {
            this.http
                .post<any>(AZURE_URL + 'zuora/read', {
                  'query': 'SELECT * FROM products'
                  }
                  , { headers })
                  .pipe(map(data => data))
                  .subscribe(data => {
                    this.accounts = data;
                    console.log('data loading complete');
                    resolve(true);
                });
        });
    }
}

这是AZURE API文档中的Curl参考 @ECHO OFF

curl -v -X POST "https://jangoepelapitest.azure-api.net/zuora/read"
-H "Ocp-Apim-Subscription-Key: {subscription key}"

--data-ascii "{body}" 

这是API定义:

{
  "openapi": "3.0.1",
  "info": {
    "title": "cosmos zuora",
    "description": "",
    "version": "1.0"
  },
  "servers": [
    {
      "url": "https://xxxxxxx.azure-api.net/zuora"
    }
  ],
  "paths": {
    "/read": {
      "post": {
        "summary": "Read",
        "description": "query accounts",
        "operationId": "5c1a4f71153ff8904fd4106a",
        "requestBody": {
          "content": { }
        },
        "responses": { }
      }
    },
    "/write": {
      "post": {
        "summary": "write",
        "description": "query accounts",
        "operationId": "5c1b45759ba2ebb7bba2c13d",
        "requestBody": {
          "content": { }
        },
        "responses": { }
      }
    },
    "/copy-5c1b6-of-/read": {
      "post": {
        "summary": "Read (clone)",
        "description": "query accounts",
        "operationId": "5c1b6b9feea787d74728b102",
        "requestBody": {
          "content": { }
        },
        "responses": { }
      }
    }
  },
  "components": {
    "securitySchemes": {
      "apiKeyHeader": {
        "type": "apiKey",
        "name": "Ocp-Apim-Subscription-Key",
        "in": "header"
      },
      "apiKeyQuery": {
        "type": "apiKey",
        "name": "subscription-key",
        "in": "query"
      }
    }
  },
  "security": [
    {
      "apiKeyHeader": [ ]
    },
    {
      "apiKeyQuery": [ ]
    }
  ]
}

所有记录应从azure资源中加载并存储在帐户中。

1 个答案:

答案 0 :(得分:0)

您必须指定httpOption observe: 'response'才能获得完整的响应并读取标头。然后检查是否存在所需的标头值,并为下一个请求设置所需的标头值。

accounts = new Subject<AccountModel[]>();

loadAccounts() {
  this.fetchAccounts().subscribe(accounts => this.accounts.next(accounts));
}

public fetchAccounts(): Observable<AccountModel[]> {
  return this.http.get<AccountModel[]>(AZURE_URL + 'zuora/read', { headers, observe: 'response' })
    .pipe(
      expand(accountsResponse => {
        const nextToken = accountsResponse.headers.get('x-ms-continuation');
        console.log('Next token:', nextToken);
        if (nextToken === null) {             
          return EMPTY;
        }

        return this.http.get<AccountModel[]>(
          AZURE_URL + 'zuora/read', 
          { headers: headers.set('x-ms-continuation', nextToken), observe: 'response' }
        );
      }),
      map(accountsResponse => accountsResponse.body),
      reduce((accData, data) => accData.concat(data), []),
    );
}