1 | # HTTP Link
|
2 |
|
3 | [![npm version](https://badge.fury.io/js/apollo-angular-link-http.svg)](https://badge.fury.io/js/apollo-angular-link-http)
|
4 | [![Get on Slack](https://img.shields.io/badge/slack-join-orange.svg)](https://www.apollographql.com/slack)
|
5 |
|
6 | ## Purpose
|
7 |
|
8 | An Apollo Link to allow sending a single http request per operation.
|
9 |
|
10 | ## Installation
|
11 |
|
12 | `npm install apollo-angular-link-http --save`
|
13 |
|
14 | ## Usage
|
15 |
|
16 | ```ts
|
17 | import {HttpLinkModule, HttpLink} from 'apollo-angular-link-http';
|
18 |
|
19 | @NgModule({
|
20 | imports: [HttpLinkModule],
|
21 | })
|
22 | class AppModule {
|
23 | constructor(httpLink: HttpLink) {
|
24 | const link = httpLink.create({uri: '/graphql'});
|
25 | }
|
26 | }
|
27 | ```
|
28 |
|
29 | ## HttpClient
|
30 |
|
31 | The HTTP Link relies on having `HttpClient` (from `@angular/common/http`)
|
32 | present in your application.
|
33 |
|
34 | ## Options
|
35 |
|
36 | HTTP Link takes an object with some options on it to customize the behavior of
|
37 | the link. If your server supports it, the HTTP link can also send over metadata
|
38 | about the request in the extensions field. To enable this, pass
|
39 | `includeExtensions` as true. If you would like to use persisted queries or just
|
40 | not to send a query, disable `includeQuery`.
|
41 |
|
42 | | name | value | default | required |
|
43 | | ----------------- | ----------------- | ---------- | -------- |
|
44 | | uri | string / function | `/graphql` | false |
|
45 | | includeExtensions | boolean | `false` | false |
|
46 | | includeQuery | boolean | `true` | false |
|
47 | | headers | HttpHeaders | `none` | false |
|
48 | | withCredentials | boolean | `none` | false |
|
49 | | method | string | `POST` | false |
|
50 |
|
51 | ## Context
|
52 |
|
53 | The HTTP Link uses the `headers` field on the context to allow passing headers
|
54 | to the HTTP request. It also supports the `withCredentials` field for defining
|
55 | credentials policy for request. These options will override the same key if
|
56 | passed when creating the the link. If some setting is different than the one in
|
57 | Options, this one will be used.
|
58 |
|
59 | | name | value | default | required |
|
60 | | ----------------- | ----------- | --------------- | -------- |
|
61 | | uri | string | `as in options` | false |
|
62 | | includeExtensions | boolean | `as in options` | false |
|
63 | | includeQuery | boolean | `as in options` | false |
|
64 | | headers | HttpHeaders | none | false |
|
65 | | withCredentials | boolean | `as in options` | false |
|
66 | | method | string | `as in options` | false |
|
67 | | useMultipart | boolean | `as in options` | false |
|
68 |
|
69 | ```js
|
70 | import {HttpLinkModule, HttpLink} from 'apollo-link-http';
|
71 | import {ApolloModule, Apollo} from 'apollo-angular';
|
72 | import {InMemoryCache} from 'apollo-cache-inmemory';
|
73 | import {HttpClientModule} from '@angular/common/http';
|
74 |
|
75 | @NgModules({
|
76 | imports: [HttpClientModule, ApolloModule, HttpLinkModule],
|
77 | })
|
78 | class AppModule {
|
79 | constructor(apollo: Apollo, httpLink: httpLink) {
|
80 | apollo.create({
|
81 | link: httpLink.create({uri: '/graphql'}),
|
82 | cache: new InMemoryCache(),
|
83 | });
|
84 | }
|
85 | }
|
86 |
|
87 | // a query with apollo-angular
|
88 | apollo.query({
|
89 | query: MY_QUERY,
|
90 | context: {
|
91 | // example of setting the headers with context per operation
|
92 | headers: new HttpHeaders().set('X-Custom-Header', 'custom-value'),
|
93 | },
|
94 | });
|
95 | ```
|
96 |
|
97 | ### Uri as function
|
98 |
|
99 | ```ts
|
100 | @NgModules({
|
101 | imports: [HttpClientModule, ApolloModule, HttpLinkModule],
|
102 | })
|
103 | class AppModule {
|
104 | constructor(apollo: Apollo, httpLink: httpLink) {
|
105 | apollo.create({
|
106 | link: httpLink.create({
|
107 | uri(operation) {
|
108 | return operation.operationName === 'login' ? '/auth' : '/graphq';
|
109 | },
|
110 | }),
|
111 | cache: new InMemoryCache(),
|
112 | });
|
113 | }
|
114 | }
|
115 | ```
|
116 |
|
117 | ### File upload
|
118 |
|
119 | In order to upload a file, you need to turn on `useMultipart` flag:
|
120 |
|
121 | ```ts
|
122 | apollo.query({
|
123 | query: MY_QUERY,
|
124 | context: {
|
125 | useMultipart: true
|
126 | },
|
127 | });
|
128 | ```
|
129 |
|
130 | ### Middleware
|
131 |
|
132 | ```ts
|
133 | import {ApolloLink} from 'apollo-link';
|
134 | import {HttpLink} from 'apollo-angular-link-http';
|
135 |
|
136 | class AppModule {
|
137 | constructor(httpLink: HttpLink) {
|
138 | const http = httpLink.create({uri: '/graphql'});
|
139 | const middleware = new ApolloLink((operation, forward) => {
|
140 | operation.setContext({
|
141 | headers: new HttpHeaders().set(
|
142 | 'Authorization',
|
143 | localStorage.getItem('token') || null,
|
144 | ),
|
145 | });
|
146 | return forward(operation);
|
147 | });
|
148 |
|
149 | const link = middleware.concat(http);
|
150 | }
|
151 | }
|
152 | ```
|
153 |
|
154 | ### Afterware (error)
|
155 |
|
156 | ```js
|
157 | import {ApolloLink} from 'apollo-link';
|
158 | import {HttpLink} from 'apollo-angular-link-http';
|
159 | import {onError} from 'apollo-link-error';
|
160 |
|
161 | import {Auth} from './auth.service';
|
162 |
|
163 | class AppModule {
|
164 | constructor(httpLink: HttpLink, auth: Auth) {
|
165 | const http = httpLink.create({uri: '/graphql'});
|
166 | const error = onError(({networkError}) => {
|
167 | if (networkError.status === 401) {
|
168 | auth.logout();
|
169 | }
|
170 | });
|
171 |
|
172 | const link = error.concat(http);
|
173 | }
|
174 | }
|
175 | ```
|