Sem Göksu
Sem Göksu
Yazılım · Yolculuk · Fenerbahçe
Angular

Angular'da Service ve Dependency Injection

Angular'ın en güçlü kavramlarından Service ve Dependency Injection'a bakıyoruz. Service nasıl yazılır, providedIn nedir, HttpClient ile API'den veri nasıl çekilir — kısacası bir Angular uygulamasının beyin takımı.

23 Nisan 2026 4 dk okuma 22 0
Merhaba arkadaşlar, bu makalemizde Angular'ın en kritik konularından biri olan Service kavramına ve bunu component'lerimize aktaran Dependency Injection (DI) mekanizmasına bakıyor olacağız. Ayrıca gerçek hayattan bir örnek olarak HttpClient kullanarak bir API'den veri çekmeyi göreceğiz.

Neden Service Kullanırız?
Angular projelerinde component'ler sadece arayüzle ilgilenmeli. İş mantığı, veri çekme, cache, validasyon, oturum yönetimi gibi işler ise service'lere yazılmalı. Bu sayede:

- Aynı mantığı birden fazla component'te tekrar yazmayız
- Component'ler daha sade ve test edilebilir olur
- Değişiklik gerektiğinde tek bir yerden müdahale ederiz

Yani service'ler aslında uygulamamızın beyni, component'ler ise yüzü. Bu ayrıştırma çok önemli.

Service Oluşturmak
Angular CLI ile pratik bir şekilde service üretebiliyoruz:

ng generate service yazi
# veya kısaltılmışı:
ng g s yazi
Bu komut bize src/app/yazi.service.ts dosyasını oluşturur. İçeriği şuna benzer:

import { Injectable } from '@@angular/core';

@@Injectable({
  providedIn: 'root'
})
export class YaziService {
  constructor() { }
}
VS Code - servis sinifi @Injectable({providedIn: 'root'}) ile tanimlaniyor.
VS Code - servis sinifi @Injectable({providedIn: 'root'}) ile tanimlaniyor.

IDE tarafinda: VS Code tarafinda @Injectable dekoratoru ekleyip constructor'a parametre verdiginizde Angular DI motoru ayaga kalkiyor. HttpClient, Router gibi sistem servisleri IntelliSense'te hazir.

@@Injectable dekoratörü bu sınıfın DI ile kullanılacağını belirtiyor. providedIn: 'root' ise service'in uygulama genelinde tekil (singleton) olarak sunulacağını söylüyor — yani nereden isterse oradan aynı instance geliyor.

Basit Bir Service Örneği
Önce bir dummy data tutan service yazalım:

import { Injectable } from '@@angular/core';

export interface Yazi {
  id: number;
  baslik: string;
  icerik: string;
  tarih: Date;
}

@@Injectable({ providedIn: 'root' })
export class YaziService {
  private yazilar: Yazi[] = [
    { id: 1, baslik: 'İlk Yazım', icerik: 'Merhaba...', tarih: new Date('2026-01-15') },
    { id: 2, baslik: 'Angular Notları', icerik: 'Data binding...', tarih: new Date('2026-02-20') }
  ];

  tumunuGetir(): Yazi[] {
    return this.yazilar;
  }

  idIleGetir(id: number): Yazi | undefined {
    return this.yazilar.find(y => y.id === id);
  }

  ekle(yazi: Yazi): void {
    this.yazilar.push(yazi);
  }
}
Service'i Component'te Kullanmak
Şimdi bu service'i bir component içerisinde kullanalım. Modern Angular'da constructor injection yerine daha sade olan inject() fonksiyonunu tercih ediyoruz:

import { Component, inject, OnInit } from '@@angular/core';
import { CommonModule } from '@@angular/common';
import { YaziService, Yazi } from './yazi.service';

@@Component({
  selector: 'app-yazi-listesi',
  standalone: true,
  imports: [CommonModule],
  template: `
    <h2>Yazılar</h2>
    @@for (y of yazilar; track y.id) {
      <article>
        <h3>{{ y.baslik }}</h3>
        <p>{{ y.icerik }}</p>
      </article>
    }
  `
})
export class YaziListesiComponent implements OnInit {
  private yaziService = inject(YaziService);
  yazilar: Yazi[] = [];

  ngOnInit() {
    this.yazilar = this.yaziService.tumunuGetir();
  }
}
Dikkat edin, biz YaziService'i kendimiz oluşturmadık (new yapmadık), Angular bizim için bunu yaptı. İşte Dependency Injection dediğimiz şey bu. Angular, sınıfın ihtiyaç duyduğu bağımlılıkları çalışma zamanında otomatik olarak inject ediyor.

HttpClient ile API'den Veri Çekmek
Gerçek projelerde veriler backend'den gelir. Angular'ın HttpClient servisini kullanarak bir API'den veri çekelim. Önce app.config.ts dosyasında HttpClient'ı sağlayıcılar listesine eklememiz gerekiyor:

import { ApplicationConfig } from '@@angular/core';
import { provideHttpClient } from '@@angular/common/http';

export const appConfig: ApplicationConfig = {
  providers: [
    provideHttpClient()
  ]
};
Şimdi service'imizi API çağrısı yapacak şekilde güncelleyelim:

import { Injectable, inject } from '@@angular/core';
import { HttpClient } from '@@angular/common/http';
import { Observable } from 'rxjs';

export interface Yazi {
  id: number;
  baslik: string;
  icerik: string;
}

@@Injectable({ providedIn: 'root' })
export class YaziService {
  private http = inject(HttpClient);
  private apiUrl = 'https://jsonplaceholder.typicode.com/posts';

  tumunuGetir(): Observable<Yazi[]> {
    return this.http.get<Yazi[]>(this.apiUrl);
  }

  idIleGetir(id: number): Observable<Yazi> {
    return this.http.get<Yazi>(`${this.apiUrl}/${id}`);
  }
}
Component tarafında ise subscribe ile Observable'ı dinleyip veriyi alıyoruz:

export class YaziListesiComponent implements OnInit {
  private yaziService = inject(YaziService);
  yazilar: Yazi[] = [];
  yukleniyor = true;
  hata = '';

  ngOnInit() {
    this.yaziService.tumunuGetir().subscribe({
      next: (veri) => {
        this.yazilar = veri;
        this.yukleniyor = false;
      },
      error: (err) => {
        this.hata = 'Yazılar yüklenirken bir hata oluştu';
        this.yukleniyor = false;
      }
    });
  }
}
Template'te de yüklenme, hata ve veri durumlarını yönetebiliriz:

@@if (yukleniyor) {
  <p>Yükleniyor...</p>
} @@else if (hata) {
  <p class="hata">{{ hata }}</p>
} @@else {
  @@for (y of yazilar; track y.id) {
    <article>
      <h3>{{ y.baslik }}</h3>
      <p>{{ y.icerik }}</p>
    </article>
  }
}
İki Önemli Nokta
- Observable'lar lazy'dir: tumunuGetir() çağırmak yetmez, subscribe() etmedikçe HTTP isteği çıkmaz.
- Memory leak'e dikkat: Component destroy olduğunda subscribe edilen Observable'ların unsubscribe edilmesi gerekir. Günümüzde en iyisi async pipe veya takeUntilDestroyed() kullanmaktır.

Özet
Bu makalede service'lerin neden önemli olduğunu, nasıl oluşturulduğunu ve Dependency Injection ile component'lere nasıl aktarıldığını gördük. Ardından HttpClient ile API'den gerçek veri çektik. Artık elimizde Angular ile basit bir uygulama yapmak için gereken tüm temel taşlar var: component, data binding, directive ve service.

5 makalelik bu başlangıç serisini buradan itibaren derinleştirebilirsiniz. Routing, Formlar, RxJS, State Management gibi konular sıradaki durak. Başarılar dilerim, sorularınızı yoruma bekliyorum...
Paylaş:

Yorumlar (0)

Henüz yorum yok. İlk yorumu sen yap!

Yorum bırak

* Yorumlar moderasyon sonrası yayınlanır. E-posta gizli tutulur.