@softeq/angular-http-data
@softeq/angular-http-data
provides
- base classes to implement common HTTP communications.
- integration of Angular
HttpClient
with@softeq/data-mappers
library
Base classes to implement common HTTP communications
This library provides helpers to implement REST-like communications.
-
First of all you have to setup this library.
@NgModule({ imports: [ SofteqHttpDataModule.forRoot({ baseUrl: 'https://api.example.com', }), ... ], ... })
where
baseUrl
points to basic part of URL all subsequent requests will be resolved upon. -
Create service that extends
AbstractRestService
class EmployeeRest extends AbstractRestService { get(id: number): Observable<Employee> { return this.httpGet(`/employees/${id}`, optimisticLockingOf(employeeMapper)); } update(employee: Employee): Observable<Employee> { return this.httpPut(`/employees/${employee.id}`, employee, optimisticLockingOf(employeeMapper)); } }
where
httpGet
andhttpPut
methods accept- URL resolved upon
baseUrl
. - body (only for
httpPut
method) -
DataMapper
(the last parameter for allhttp*
methods)
- URL resolved upon
There are several http*
methods defined in AbstractRestService
:
-
httpGet
forGET
request -
httpPost
forPOST
request -
httpPut
forPUT
request -
httpDelete
forDELETE
request -
httpRequest
allows to send request of any method.
HttpClient
with @softeq/data-mappers
Integration of Angular If you want to use DataMapper
s, but do not like AbstractRestService
you can use DataMapper
s directly with HttpClient
,
but in this case you have to map requests/responses manually.
- In order to map
HttpRequest
transforms body of request using givenmergeRequestWithMapper<S, R>(request: HttpRequest<S>, body?: S, requestMapper?: HttpDataMapper<S>, responesMapper?: HttpDataMapper<R>): HttpRequest<any>
requestMapper
,
responseMapper
is optional here, but sometimes it is necessary to define correctresponseType
ofHttpRequest
(only for non-json
responseType
). - In order to map
HttpResponse
transforms response using providedparseResponseWithMapper<T>(response: HttpResponse<T>, responseMapper?: HttpDataMapper<T>): T
responseMapper
.
Support of pageable REST resources
Tables often show data by pages or have infinite scroll, where only visible part of content is fetched from the server.
In both cases we have to return data by chunks. @softeq/angular-http-data
library provides AbstractPaginationRestService
to implement such behavior.
Look at the following example
class EmployeeRest extends AbstractPaginationRestService {
findAllByNameAsDataSource(name: string): SlicedDataSource {
return this.createSlicedDataSourceGet(`/employees`, { name }, identityMapper(), arrayMapperOf(employeeMapper));
}
}
Here we use createSlicedDataSourceGet
method which
- accepts URL of the target endpoint
- accepts request body (for
GET
request body is merged into URL as query parameters) - accepts
DataMapper
for request body - accepts
DataMapper
for response body (body is always array of data) - returns
SlicedDataSource
.
SlicedDataSource
allows to select
data by chunks
const dataSource = this.employeeRest.findAllByNameAsDataSource('John');
const slicedData$ = dataSource.select({
from: 0,
to: 25,
sorting: { field: 'name', direction: SortDirection.Descending },
});
slicedData$.subscribe((slicedData: SlicedData) => {
slicedData.data; // chunk of returned data
slicedData.total; // total number of data
});
There are several createSlicedDataSource*
methods defined in AbstractPaginationRestService
:
-
createSlicedDataSourceGet
forGET
request -
createSlicedDataSourcePut
forPUT
request -
createSlicedDataSourcePost
forPOST
request -
createSlicedDataSource
allows to send request of any method
AbstractPaginationRestService
relies on
Protocol AbstractPaginationRestService
is opinionated regarding protocol used for paging.
It uses Range
header to perform request.
Range: items=0-24
The server should respond with a Content-Range
header to indicate how many items are being returned
and how many total items exist.
Content-Range: items 0-24/66
Body of response should be a chunk (Array
) of retrieved data.
[
{
"id": 1,
"name": "John"
},
{
"id": 2,
"name": "Mark"
},
...
]