Angular 4 HttpClient с сервером HATEOAS REST

Мое приложение Angular 4 использует сервер Spring Data REST API HATEOAS, я использую HttpClient и вижу, что оно возвращает Object вместо any, например http. Я прочитал этот вопрос: https://stackoverflow.com/questions/45133992/why-does-the-httpclient-in-angular-4-3-return-object-instead-of-any, и я понял. У меня есть сложный json со многими такими полями:

{
  "_embedded": {
    "customers": [
      {
        "sid": "c44fdb6f-9b7c-4f75-8d4c-7542f54037b7",
        "createdDate": "2017-08-01T13:06:23Z",
        "lastModifiedDate": "2017-08-01T13:06:23Z",
        "lastModifiedBy": "admin",
        "name": "Customer 1",
        "username": "customer1",
        "address": "Via xxxxx",
        "city": "Adria",
        "landlinePhone": "+39042000000",
        "mobilePhone": null,
        "email": "[email protected]",
        "fax": null,
        "vatNumber": "IT01000020295",
        "taxCode": null,
        "iban": null,
        "swift": null,
        "enableEcommerce": true,
        "balance": 0,
        "enabled": true,
        "new": false,
        "_links": {
          "self": {
            "href": "....:8080/api/v1/customers/1"
          },
          "customer": {
            "href": "....:8080/api/v1/customers/1"
          },
          "movements": {
            "href": "....:8080/api/v1/customers/1/movements"
          },
          "country": {
            "href": "....:8080/api/v1/customers/1/country"
          }
        }
      }
    ]
  },
  "_links": {
    "self": {
      "href": "....:8080/api/v1/customers{?page,size,sort}",
      "templated": true
    },
    "profile": {
      "href": "....:8080/api/v1/profile/customers"
    },
    "search": {
      "href": "....:8080/api/v1/customers/search"
    }
  },
  "page": {
    "size": 20,
    "totalElements": 1,
    "totalPages": 1,
    "number": 0
  }
}

HttpClient не позволяет делать response.page.totalElements, потому что, как я уже сказал, тип ответа — это объект, а не тип any. Мне интересно, как лучше всего достичь моей цели; У меня есть 2 идеи:

  • Отправьте ответ на any. В этом случае я, конечно, смогу получить доступ к полям без проверки типов.

  • Создайте несколько объектов для сопоставления ответа HATEOAS: вероятно, мне потребуется как минимум 2-3 интерфейса и 1 класс для каждого объекта модели. Этот подход кажется довольно сложным, возможно, излишним по сравнению с первым решением, и мне всегда нужно приведение от объекта к моей конкретной модели объекта; это означает, что у меня может быть исключение во время выполнения из-за неправильного приведения типа.

Не могли бы вы дать мне несколько советов и лучших практик, чтобы достичь моей цели и следовать идее, которую нарисовала команда angular?


person Alessandro Celeghin    schedule 01.08.2017    source источник
comment
Вы пробовали response['page'].totalElements?   -  person Mackelito    schedule 16.08.2017


Ответы (1)


У меня такая же проблема, и я нашел одно возможное решение:

// Java: Spring Data REST Repository
@RepositoryRestResource(collectionResourceRel = "result", path = "customers")
public interface CustomerRepository extends PagingAndSortingRepository<Customer, Long> {
}

// TypeScript model
export interface ListResult<T> {
   _embedded: EmbeddedList<T>;
  _links: any;
  page: any;
}

export interface EmbeddedList<T> {
  results: T[];
}

export class Customer{
  name: String;
  ... bla bla ...
}

// AJAX Call
http.get('/api/customers').subscribe(response => {
  const customers: Customer[] = response._embedded.results;
});

Все репозитории должны иметь collectionResourceRel="results".

person Martin Mahr    schedule 02.11.2017