TypeScript - Angular'da Genel (Generic) metod oluşturma için En İyi Uygulama


Angular'da HttpClient kullanarak Api uç noktalarını tasarlıyorum. Bu, tüm Rest çağrılarını yönetecek tek bir servis sınıfıdır, diğer servis sınıflarından çağrılacaktır (şu anda Rest çağrıları yapanlar).

Genel bir Rest yöntemi yapmak için en iyi uygulama nedir.

getApi(url: string, options?: object): Observable<any> {
    return this.http.get<any>(url, options).pipe(
      catchError((error: HttpErrorResponse) => {
        return throwError(error);
    })
  )
}

Veya

getApi<T>(url: string, options?: object): Observable<T> {
    return this.http.get<T>(url, options).pipe(
      catchError((error: HttpErrorResponse) => {
        return throwError(error);
    })
  )
}

Yukarıdakilerden herhangi biri : HttpEvent, HttpResponse veya benzeri diğer yanıtları işleyebilecek mi?

Bunu yönetmek için birden fazla yöntem mi yapmalıyım?

Cevap #1

Lütfen dikkat edin, cevap tamamen görüşe dayalıdır.

Çözümümü göstermeden önce, onun altındaki fikri paylaşmak istiyorum. Yani, TS ile çalışırken mümkün olduğunca katı türlere sahip olmayı bekliyorum. Bu nedenle, any, object veya bunun gibi şeyleri kullanmak bu bağlamda dikkat dağıtıcıdır. Ayrıca, herhangi bir ekstra tür dönüşümünden kaçınmak istiyorum, çünkü bu bir yerde hataya yol açacaktır.

Neyse ki, TS bu konuda bana yardımcı olacak kadar akıllı, çünkü kullanıma bağlı olarak türleri tanımlayabiliyor.

Buna dayanarak şöyle bir şey inşa edebiliriz:

İhtiyacımız olan her şeyi yapabilen çok genel bir sınıf (fetch'e parametre geçirme, loglama, sayaç veya ihtiyacınız olan her şeyle genişletilebilir)

class HttpService {
    get<TData, TResult>(url: string, data?: TData): Promise<TResult> {
        return fetch(url, data)
            .then(x => x.json())
            .catch((err) => console.log(err));
    }
}

Ama bu sınıf doğrudan kullanılmamalıdır. İzole edilmiş getirme mantığını sağlayacak ve generikler yerine sıkı tipler sunacak daha katı ve özel bir servis oluşturmanızı tavsiye ederim.

type User = {
    name: string;
}

class MyDataService {

    constructor(private readonly _transportService: HttpService) { }
    fetchUserInfo(userId: number): Promise<User> {
        return this._transportService.get('/some/url', userId);
    }
}

Artık MyDataService'i herhangi bir tür dönüştürme ve tür tahmini yapmadan kullanabilirim. Bir diğer fayda ise bu servisin çok kolay test edilebilir olmasıdır çünkü taşıma modülünü istediğiniz gibi değiştirebilirsiniz.

Umarım cevabım sana yardımcı olmuştur.