|
1 | 1 | # Slicknode Apollo Link |
2 | 2 |
|
3 | | -ApolloLink component to use [slicknode-client](https://github.com/slicknode/slicknode-client) |
4 | | -with [apollo-client](https://www.apollographql.com/client). |
| 3 | +ApolloLink component that automatically sets authentication headers for GraphQL requests via the [apollo-client](https://www.apollographql.com/client). It stores the access and refresh tokens in a store (for example InMemory, localStorage, sessionStorage etc.) and keeps track of expiration times. |
| 4 | +If auth tokens expire, they are automatically refreshed in the background when a request is issued, without interruption to the user. Can be combined with any of the available [apollo links](https://www.apollographql.com/docs/link/#linkslist). |
5 | 5 |
|
6 | 6 | ## Installation |
7 | 7 |
|
8 | | -Install both the [slicknode-client](https://github.com/slicknode/slicknode-client) and the |
9 | | -[slicknode-apollo-link](https://github.com/slicknode/slicknode-apollo-link) npm package: |
| 8 | +Install the [slicknode-apollo-link](https://github.com/slicknode/slicknode-apollo-link) npm package: |
10 | 9 |
|
11 | | - yarn add slicknode-client slicknode-apollo-link |
| 10 | + yarn add slicknode-apollo-link |
| 11 | + |
| 12 | +There is also a peer dependencie to `graphql` which you should already have installed when you are using the [apollo-client](https://www.apollographql.com/client). |
12 | 13 |
|
13 | 14 | ## Usage |
14 | 15 |
|
15 | 16 | This is a minimal example to create an instance of an apollo client. Refer to the documentation of the |
16 | | -[slicknode-client](https://github.com/slicknode/slicknode-client) and the [apollo-client](https://www.apollographql.com/client) |
17 | | -to learn how to use and customize it: |
| 17 | +[apollo-client](https://www.apollographql.com/client) to learn how to use and customize it: |
18 | 18 |
|
19 | | -```typescript |
20 | | -import SlicknodeClient from 'slicknode-client'; |
| 19 | +```javascript |
21 | 20 | import SlicknodeLink from 'slicknode-apollo-link'; |
22 | 21 | import { ApolloClient } from 'apollo-client'; |
23 | 22 | import { InMemoryCache } from 'apollo-cache-inmemory'; |
| 23 | +import { ApolloLink } from 'apollo-link'; |
| 24 | +import { HttpLink } from 'apollo-link-http'; |
24 | 25 |
|
25 | | -// Create an instance of the slicknode-client |
26 | | -const slicknodeClient = new SlicknodeClient({ |
27 | | - // Set your Slicknode GraphQL endpoint here |
28 | | - endpoint: 'https://myproject.slicknode.com' |
29 | | -}); |
| 26 | +const slicknodeLink = new SlicknodeLink(); |
30 | 27 |
|
31 | 28 | // Create the ApolloClient instance to use in your projects |
32 | | -const apolloClient = new ApolloClient({ |
33 | | - // Pass the Slicknode client to the link that should be used by the ApolloClient |
34 | | - link: new SlicknodeLink({ |
35 | | - client: slicknodeClient |
36 | | - }), |
| 29 | +const client = new ApolloClient({ |
| 30 | + link: ApolloLink.from([ |
| 31 | + // Add the slicknode link somewhere before the HttpLink |
| 32 | + slicknodeLink, |
| 33 | + |
| 34 | + // ... more links (retry, error handling etc.) |
| 35 | + |
| 36 | + new HttpLink({ |
| 37 | + // Add your slicknode GraphQL endpoint here |
| 38 | + uri: 'https://you-project.slicknode.com', |
| 39 | + credentials: 'same-origin', |
| 40 | + }), |
| 41 | + ]), |
37 | 42 |
|
38 | 43 | // Add a cache (required by apollo, change as needed...) |
39 | 44 | cache: new InMemoryCache() |
40 | 45 | }); |
41 | 46 |
|
42 | | -// Use the apolloClient as usual... (See apollo-client documentation) |
| 47 | +// Use the client as usual... (See apollo-client documentation) |
43 | 48 | ``` |
44 | 49 |
|
45 | | -### Usage with authenticators |
| 50 | +### Authentication |
| 51 | + |
| 52 | +To authenticate the client on the server and obtain an auth token set, you can execute any mutation |
| 53 | +that returns such data. By adding the directive `@authenticate` to the mutation, the `SlicknodeLink` |
| 54 | +automatically picks up the tokens, stores them on the client and adds the required authentication headers |
| 55 | +to subsequent requests. |
| 56 | + |
| 57 | +Make sure that the module with the login mutation is installed and deployed to your Slicknode server. See the list of |
| 58 | +[available auth modules](#available-auth-modules) for details. |
| 59 | + |
| 60 | +For example: |
| 61 | + |
| 62 | +```javascript |
| 63 | +import { gql } from 'graphql-tag'; |
| 64 | + |
| 65 | +client.query(gql` |
| 66 | + mutation LoginUser { |
| 67 | + loginEmailPassword(input: {email: "[email protected]", password: "xyz123"}) @authenticate { |
| 68 | + accessToken |
| 69 | + refreshToken |
| 70 | + accessTokenLifetime |
| 71 | + refreshTokenLifetime |
| 72 | + } |
| 73 | + }` |
| 74 | +) |
| 75 | + .then(result => { |
| 76 | + console.log(''); |
| 77 | + }) |
| 78 | + .catch(err => { |
| 79 | + console.log('Something went wrong: ', err.message); |
| 80 | + }); |
| 81 | +``` |
46 | 82 |
|
47 | | -To use the `SlicknodeLink` instance in combination with the available authenticators, use the |
48 | | -`SlicknodeClient` instance directly that was passed to the link component. Once the `SlicknodeClient` is authenticated, |
49 | | -the `ApolloClient` instance will also make requests as the authenticated user. |
50 | 83 |
|
51 | | -```typescript |
52 | | -// Create slicknode client / apollo client and link as described above |
53 | | -// Then use any authenticator: |
| 84 | +### Logout |
| 85 | + |
| 86 | +To log the user out, you can execute the `logoutUser` mutation. This automatically deletes the auth tokens |
| 87 | +from the store when successful and invalidates the refresh token no the server: |
| 88 | + |
| 89 | +```javascript |
| 90 | +client.query({ |
| 91 | + query: gql`mutation LogoutUser($token: String) { |
| 92 | + logoutUser(input: {refreshToken: $token}) { |
| 93 | + success |
| 94 | + } |
| 95 | + }`, |
| 96 | + variables: { |
| 97 | + // Get the current refreshToken from the SlicknodeLink instance to invalidate it on the server |
| 98 | + token: slicknodeLink.getRefreshToken() |
| 99 | + } |
| 100 | +) |
| 101 | + .then(result => { |
| 102 | + console.log('Login successful', result.data.logoutUser); |
| 103 | + }) |
| 104 | + .catch(err => { |
| 105 | + console.log('Something went wrong: ', err.message); |
| 106 | + }); |
| 107 | +``` |
54 | 108 |
|
55 | | -import login from 'slicknode-auth-email-password'; |
| 109 | +### Available Auth Modules |
56 | 110 |
|
57 | | -slicknodeClient. authenticate( login( '[email protected]', 'mysecretpassword')) |
58 | | - .then(() => { |
59 | | - console.log('Login successful'); |
60 | | - }) |
61 | | - .catch(e => { |
62 | | - console.log('Something went wrong: ' + e.message); |
63 | | - }); |
64 | | -``` |
65 | 111 |
|
66 | | -**Tipp:** You might want to invalidate the cached data in the apollo client once the authentication state changes |
67 | | -inside of the slicknode client. |
|
0 commit comments