Angular предоставляет встроенный модуль для работы с серверными
запросами — HttpClient, входящий в пакет
@angular/common/http. Он построен поверх RxJS и полностью
основан на Observable-потоках, что определяет ключевые
принципы обработки ответов сервера.
Подключение выполняется через импорт HttpClientModule в
корневом или функциональном модуле:
import { HttpClientModule } from '@angular/common/http';
@NgModule({
imports: [HttpClientModule]
})
export class AppModule {}
HttpClient автоматически:
Типичный HTTP-ответ включает:
По умолчанию HttpClient возвращает только тело ответа,
но при необходимости можно получить полный объект ответа.
this.http.get<User[]>('/api/users');
Для доступа ко всем данным:
this.http.get<User[]>('/api/users', {
observe: 'response'
});
В этом случае возвращается
HttpResponse<User[]>.
Angular поощряет строгую типизацию данных, приходящих с сервера. Тип указывается через generic-параметр:
interface User {
id: number;
name: string;
email: string;
}
this.http.get<User>('/api/user/1');
Преимущества:
Типизация не выполняет runtime-проверку, но служит важным инструментом архитектурной стабильности.
Так как HttpClient возвращает Observable,
обработка выполняется через subscribe или
RxJS-операторы.
Простейший вариант:
this.http.get<User[]>('/api/users')
.subscribe(users => {
this.users = users;
});
Для более сложной логики применяются операторы pipe:
this.http.get<User[]>('/api/users').pipe(
map(users => users.filter(u => u.active)),
tap(users => console.log(users))
);
Распространённые операторы:
map — преобразование данных;tap — побочные эффекты без изменения потока;filter — фильтрация;switchMap — подмена запроса другим.Ошибки перехватываются через оператор catchError или
второй аргумент subscribe.
this.http.get<User[]>('/api/users').subscribe({
next: users => this.users = users,
error: err => this.errorMessage = err.message
});
Более масштабируемый подход:
this.http.get<User[]>('/api/users').pipe(
catchError(error => {
if (error.status === 404) {
return of([]);
}
return throwError(() => error);
})
);
Тип ошибки — HttpErrorResponse, содержащий:
status — HTTP-код;message — текст ошибки;error — тело ответа сервера.Для исключения дублирования логики используется HTTP-interceptor.
@Injectable()
export class ErrorInterceptor implements HttpInterceptor {
intercept(req: HttpRequest<any>, next: HttpHandler) {
return next.handle(req).pipe(
catchError((error: HttpErrorResponse) => {
console.error(error);
return throwError(() => error);
})
);
}
}
Регистрация:
providers: [
{
provide: HTTP_INTERCEPTORS,
useClass: ErrorInterceptor,
multi: true
}
]
Интерсепторы позволяют:
Angular не навязывает логику обработки HTTP-статусов, но предоставляет всю информацию.
this.http.get('/api/data', { observe: 'response' })
.subscribe(response => {
if (response.status === 204) {
// пустой ответ
}
});
На практике статус-коды обрабатываются:
Если сервер возвращает не JSON, необходимо указать тип ответа:
this.http.get('/api/file', {
responseType: 'blob'
});
Варианты responseType:
json (по умолчанию);text;blob;arraybuffer.Пример обработки текстового ответа:
this.http.get('/api/version', { responseType: 'text' })
.subscribe(version => {
this.version = version;
});
Часто сервер возвращает данные в формате, неудобном для фронтенда. Преобразование выполняется на уровне сервиса:
this.http.get<any[]>('/api/users').pipe(
map(data => data.map(item => ({
id: item.user_id,
name: item.full_name
})))
);
Это:
RxJS позволяет кэшировать результаты запросов:
users$ = this.http.get<User[]>('/api/users').pipe(
shareReplay(1)
);
shareReplay:
Отписка от Observable автоматически отменяет
HTTP-запрос:
const sub = this.http.get('/api/data').subscribe();
sub.unsubscribe();
В связке с switchMap отмена происходит автоматически при
новом запросе:
this.search$.pipe(
switchMap(term => this.http.get(`/api/search?q=${term}`))
);
Корректная обработка ответов сервера предполагает:
Пример сервиса:
@Injectable({ providedIn: 'root' })
export class UserService {
constructor(private http: HttpClient) {}
getUsers() {
return this.http.get<User[]>('/api/users');
}
getUser(id: number) {
return this.http.get<User>(`/api/users/${id}`);
}
}
Компонент получает уже готовые данные без знания деталей HTTP-ответа.
Angular поддерживает работу с Observable напрямую в
шаблонах через async pipe:
<ul>
<li *ngFor="let user of users$ | async">
{{ user.name }}
</li>
</ul>
async:
Это снижает количество ручного кода и уменьшает риск утечек памяти.
Обработка ответов сервера в Angular — это не просто получение данных, а полноценный слой приложения, включающий:
Грамотно выстроенная система обработки ответов делает приложение устойчивым к изменениям API, упрощает поддержку и масштабирование, а также формирует чёткое разделение ответственности между слоями приложения.