feat: Add a link that uses angulars httpCient
Nobody has claimed this yet.
- Dominant language
- TypeScript
- Stars
- 40.6k
- Forks
- 1.7k
- Avg merge
- 1d 22h
- Merged PRs (30d)
- 22
Description
Describe the feature you'd like to request
It would be great to have a trpc link that supports the angular httpClient.
This would allow angular developers to use the usual interceptors to add headers and similar. Additionally it would also help in SSR use cases as the httpClient can cache requests so that they don't have to be repeated on the client.
Describe the solution you'd like to see
I think ideally there is a kind of Client interface that can be implemented and then dropped into any of the existing links to make sure the requests are sent by the httpCLient.
Describe alternate solutions
I think alternatively, a new link could be implmented that works with the httpClient.
I tried to implement such a client and it seems to work so far. But since I could not understand the entire model of the current clients, I'm sure it lacks some features. I will paste it here as a reference anyways.
import { inject, InjectionToken } from '@angular/core';
import type { AppRouter } from '@evorto/server/appRouter';
import { HttpClient } from '@angular/common/http';
import { CreateTRPCClient, createTRPCClient, TRPCLink } from '@trpc/client';
import type { AnyRouter } from '@trpc/server';
import { observable } from '@trpc/server/observable';
import superjson, { SuperJSONResult } from 'superjson';
const TRPC_CLIENT = new InjectionToken<CreateTRPCClient<AppRouter>>(
'TRPC_CLIENT',
);
export interface AngularLinkOptions {
url: string;
}
const angularLink = (http: HttpClient) => {
return <TRouter extends AnyRouter>(
opts: AngularLinkOptions,
): TRPCLink<TRouter> => {
return (runtime) =>
({ op }) =>
observable((observer) => {
const url = `${opts.url}/${op.path}`;
switch (op.type) {
case 'subscription':
throw new Error('Subscriptions are not supported');
case 'query': {
http
.get<{
result: { data: SuperJSONResult };
}>(url, {
params: {
input: JSON.stringify(superjson.serialize(op.input)),
},
})
.subscribe((res) => {
const parsedResponse = superjson.deserialize(res.result.data);
observer.next({
result: {
type: 'data',
data: parsedResponse,
},
});
observer.complete();
});
break;
}
case 'mutation': {
http
.post<{
result: { data: SuperJSONResult };
}>(url, superjson.serialize(op.input))
.subscribe((res) => {
const parsedResponse = superjson.deserialize(res.result.data);
observer.next({
result: {
type: 'data',
data: parsedResponse,
},
});
observer.complete();
});
break;
}
}
});
};
};
export const provideTrpcClient = () => {
return {
provide: TRPC_CLIENT,
useFactory: (http: HttpClient) => {
const link = angularLink(http);
return createTRPCClient<AppRouter>({
links: [link({ url: '/trpc' })],
});
},
deps: [HttpClient],
};
};
export function injectTrpcClient() {
return inject(TRPC_CLIENT);
}
Additional information
No response
👨👧👦 Contributing
- 🙋♂️ Yes, I'd be down to file a PR implementing this feature!
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start by reviewing the repository’s existing tRPC links and client model, then compare their request lifecycle with Angular HttpClient. Done means an agreed Angular HttpClient-backed integration supports the requested use cases, including interceptors and SSR request caching.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- angular, typescript
- Domain
- api, frontend
- Issue type
- Feature
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 35/100