DEV Community

kbartsch
kbartsch

Posted on • Originally published at Medium on

Mastering External API Usage in Angular Interceptors with x-api-key


Image by T Hansen from Pixabay

Introduction : In Angular development, managing API calls to multiple endpoints is common. Some endpoints may require an x-api-key for authentication, while others don’t. Instead of hardcoding headers in each service, Angular’s HttpInterceptor allows us to centralize request handling and apply API keys conditionally. Let’s explore how to implement this and the pros and cons of conditional key management. (For only readers Step 4is the important one)

Level: For everyone

Note: In this tutorial, we’ll build a simple Angular 19 application to fetch news articles using the Finlight.me News API . While this guide uses Finlight.me to demonstrate managing an x-api-key, you can easily adapt the approach for any API requiring custom headers. Our focus will be on creating an interceptor to handle the x-api-key and applying it selectively to specific API requests.

Step 1: Set Up Your Angular Project

First, create a new Angular project and install required dependencies. (NodeJS installation required)

  1. Create a new Angular project :
npx -p @angular/cli ng new angular-news-app 
cd angular-news-app
Enter fullscreen mode Exit fullscreen mode
  1. Generate the Environments files for your project:
npx -p @angular/cli ng generate environments
Enter fullscreen mode Exit fullscreen mode
  1. Open your project in your favorite editor (e.g., VS Code).

Step 2: Obtain the Finlight API Key

  1. Go to Finlight.me and create an account or use alternativ APIs.
  2. Navigate to the API Keys section in the menu after logging in.
  3. Copy your free API key.

Step 3: Configure the Environment File

Store your API key in Angular’s environment configuration file for secure and environment-specific management.

  1. Open src/environments/environment.development.ts and add your API key:
export const environment = {   
  production: false,   
  finlightApiKey: 'your-finlight-api-key-here' 
};
Enter fullscreen mode Exit fullscreen mode
  1. Open src/environments/environment.ts and update the finlightApiKey for production:
export const environment = {
  production: true,
  finlightApiKey: 'your-production-finlight-api-key-here'
};
Enter fullscreen mode Exit fullscreen mode

Step 4: Create the Interceptor

We’ll create an interceptor to attach the x-api-key header only to Finlight’s API requests.

  1. Generate the interceptor:
ng generate interceptor interceptors/api-key
Enter fullscreen mode Exit fullscreen mode
  1. Implement the interceptor in src/app/interceptors/api-key.interceptor.ts:
import { Injectable } from '@angular/core';
import { HttpInterceptor, HttpRequest, HttpHandler, HttpEvent } from '@angular/common/http';
import { Observable } from 'rxjs';
import { environment } from '../../environments/environment';

@Injectable()
export class ApiKeyInterceptor implements HttpInterceptor {
  private apiKey = environment.finlightApiKey;

  intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
    const finlightUrlPattern = 'https://api.finlight.me'; // Match Finlight API endpoints

    if (req.url.includes(finlightUrlPattern)) {
      const secureReq = req.clone({
        headers: req.headers.set('x-api-key', this.apiKey)
      });
      return next.handle(secureReq);
    }

    // Forward requests to non-secure APIs without modifying
    return next.handle(req);
  }
}
Enter fullscreen mode Exit fullscreen mode
  1. Register the interceptor in AppModule (src/app/app.module.ts):
import { HTTP_INTERCEPTORS } from '@angular/common/http';
import { ApiKeyInterceptor } from './interceptors/api-key.interceptor';

@NgModule({
  providers: [
    { provide: HTTP_INTERCEPTORS, useClass: ApiKeyInterceptor, multi: true }
  ]
})
export class AppModule {}
Enter fullscreen mode Exit fullscreen mode

Step 5: Create the News Service

We’ll create a service to fetch data from the Finlight API.

  1. Generate the service:
ng generate service services/news
Enter fullscreen mode Exit fullscreen mode
  1. Implement the service in src/app/services/news.service.ts:
import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { Observable } from 'rxjs';

@Injectable({
  providedIn: 'root'
})
export class NewsService {
  private apiUrl = 'https://api.finlight.me/v1/articles';

  constructor(private http: HttpClient) {}

  // Fetch news from Finlight API
  getNews(): Observable<any> {
    return this.http.get(this.apiUrl);
  }
}
Enter fullscreen mode Exit fullscreen mode

Step 6: Build the News Component

Create a component to display the news.

  1. Generate the component:
ng generate component components/news
Enter fullscreen mode Exit fullscreen mode
  1. Update src/app/components/news/news.component.ts:
import { Component, OnInit } from '@angular/core';
import { NewsService } from '../../services/news.service';

@Component({
  selector: 'app-news',
  templateUrl: './news.component.html',
  styleUrls: ['./news.component.css']
})
export class NewsComponent implements OnInit {
  newsArticles: any[] = [];

  constructor(private newsService: NewsService) {}

  ngOnInit(): void {
    this.newsService.getNews().subscribe({
      next: (data) => (this.newsArticles = data.articles),
      error: (err) => console.error('Error fetching news:', err)
    });
  }
}
Enter fullscreen mode Exit fullscreen mode
  1. Update the component’s template in src/app/components/news/news.component.html:
<div class="news-container">
  <h1>Latest News</h1>
  <div *ngFor="let article of newsArticles" class="news-article">
    <h2>{{ article.title }}</h2>
    <p>{{ article.publishDate}}</p>
    <a [href]="article.link" target="_blank">Read More</a>
  </div>
</div>
Enter fullscreen mode Exit fullscreen mode
  1. Add some styles in src/app/components/news/news.component.css:
.news-container {
  padding: 20px;
  font-family: Arial, sans-serif;
}
.news-article {
  border-bottom: 1px solid #ccc;
  margin-bottom: 20px;
  padding-bottom: 10px;
}
a {
  color: #007bff;
  text-decoration: none;
}
a:hover {
  text-decoration: underline;
}
Enter fullscreen mode Exit fullscreen mode

Step 7: Add the News Component to the App

  1. Update src/app/app.component.html to include the NewsComponent:
<app-news></app-news>
Enter fullscreen mode Exit fullscreen mode
  1. Serve the app in the terminal:
npm start
Enter fullscreen mode Exit fullscreen mode

Step 8: Test the Application

  1. Open your browser and navigate to http://localhost:4200.
  2. The app will fetch and display the latest news from the Finlight API.
  3. Check the network requests in your browser’s developer tools to verify that the x-api-key is attached to requests to the secure API.

Final Thoughts

In this tutorial, you’ve built a simple Angular app that fetches news articles using the Finlight API. By leveraging an Angular interceptor, you managed the x-api-key authentication in a clean, reusable way, applying it only to secure requests.

This approach not only simplifies your code but also scales well for applications interacting with multiple APIs. Remember to keep your API keys secure and consider moving sensitive operations to the backend for production-grade security. There is also many things to learn and also to improve for example move the api url into an constant or use the new control flow from angular 17, but that is another story.

Happy coding! 🚀

Top comments (0)