I think it can be common problem for many other developers, but I didn't found some efficient solution yet.
I'm working on Angular2 project. Of course I have many places when I need to make http calls to manage my data. So I'm using Http service and everything works as expected.
On some architecture stage (when team have implemented most of pages), new requirement comes into place - now we need to connect deeper our server and client so additional header should be added to all requests initiated from client (it can be authenticated bearer token, method override instruction to pass firewall, many other).
Not a problem at all. 10 min to accomplish:
- creating new service
MyHttp - re-imlementing all
get,post,put,deletemethods with adding required headers - mass replace all
Httpreferences with newMyHttp - work done
But this approach is not good when you have many developers involved:
- Some wiki resource should be created and defined new rules with accessing server. All developers from all teams should start follow this rules immediately
- There is a risk that old
Httpservice instead ofMyHttpwill be re-used as both services are accessible, so incorrect behavior will be introduced - More pain for server team to find incorrect behavior when incorrect client http service was chosen
So more suitable approach for multi-team development - is to use @NgModule module class annotation to replace old Http service with new MyHttp using provide configuration:
@NgModule({
declarations: [ ... ],
imports: [ ... ],
providers: [..., {provide: Http, useClass: MyHttp}],
bootstrap: [AppComponent]
})
From my point of view this approach has many advantages:
- no need to modify files and replace
HttptoMyHttp - no need to change developer rules in using
Httpservice - assure that server side always receive proper headers
- no worry about incidentally using
MyHttpinstead ofHttp- they behave equally
The only problem, that we are creating cyclic dependency as inside MyHttp we need to use old Http
@Injectable()
export class HttpService {
constructor(private http: Http) {
}
get(url: string) { return this.http.get(url); }
post(url: string, data: any) { ...}
...
}
So exception is thrown:
Cannot instantiate cyclic dependency!
So the only way - is to create MyHttp totally independent from Http. But it adds more complexity to code. And such kind of implementation smell, to be honest.
Is any solutions how to use Http inside MyHttp using configuration defined above?
Thanks.