kamilkisiela / apollo-angular

A fully-featured, production ready caching GraphQL client for Angular and every GraphQL server 🎁
https://apollo-angular.com
MIT License
1.5k stars 310 forks source link

upgrading apollo client to latest version for unsupported transport package with websocket subscriptions #1801

Closed neaplus closed 1 year ago

neaplus commented 2 years ago

Describe the bug

apollographql/subscriptions-transport-ws is not supported, nor maintained. Please, use https://github.com/enisdenjo/graphql-ws.

To Reproduce using websocket based subscription queries

Expected behavior not working and suggests switching graphql-ws which latest version of apollo-client uses

Environment:

- @angular/cli@XX.YY.ZZ
- @angular/core@XX.YY.ZZ
- @apollo/client@XX.YY.ZZ
- apollo-angular@XX.YY.ZZ
- graphql@XX.YY.ZZ
- typescript@XX.YY.ZZ

Additional context

neaplus commented 2 years ago

https://github.com/apollographql/apollo-client/releases/tag/v3.6.0

KeithGillette commented 2 years ago

While the Apollo Angular Subscriptions documentation should be updated for the deprecation of subscriptions-transport-ws, there's no incompatibility between Apollo Angular and graphql-ws. The graphql-ws Apollo Client example can be adapted for Apollo Angular.

neaplus commented 2 years ago

Actually, the issue is some of graphql backend frameworks (For example: spring-graphql) seem stop supporting old deprecated subscriptions-transport-ws protocol. Since current apollo-client already deprecated it in their documantation and switched to new protocol, and considering apollo-angular's apollo-client dependency version 3.5.9 comparing to 3.6.9 is also pretty outdated, I think it's good to upgrading newer version and switching to graphql-ws protocol would be great.

In addition, subscriptions-transport-ws is very outdated. It'd be very nice to switch graphql-ws asap.

thanks in advance!

KeithGillette commented 2 years ago

We've upgraded to @apollo/client@3.6.8 and graphql-ws@5.9.0 in our apollo-angular@3.0.1 project.

neaplus commented 2 years ago

We've upgraded to @apollo/client@3.6.8 and graphql-ws@5.9.0 in our apollo-angular@3.0.1 project.

you mean, it's possible to use graphql-ws protocol with apollo-angular@3.0.1? Bcoz, I didn't succeed to configure and use it last time what i've been tried.

KeithGillette commented 2 years ago

Yes, I was able to get graphql-ws + ws to work with @apollo/client 3.6.0-3.6.8 and apollo-angular@3.0.1, replacing the deprecated subscriptions-transport-ws WebSocket implementation our project previously used with older versions of @apollo/client.

neaplus commented 2 years ago

indeed, it works 🤌 thanks dude. I'll drop a simple sample here as well in case of someone needs, since It's not documented.

neaplus commented 2 years ago

Subscription queries by using graphql-ws with apollo-angular@3x and angular@13x

package.json

"dependencies": {
...
"@angular/core": "~13.x",
"@apollo/client": "3.6.8",
"apollo-angular": "^3.0.1",
"graphql": "^16",
"graphql-ws": "5.9.0",
...
},

graphql.module.ts


import { NgModule } from '@angular/core';
import { ApolloModule, APOLLO_OPTIONS } from 'apollo-angular';
import { HttpLink } from 'apollo-angular/http';
import { split, ApolloClientOptions, InMemoryCache } from '@apollo/client/core';
import { getMainDefinition } from '@apollo/client/utilities';
import { GraphQLWsLink } from '@apollo/client/link/subscriptions';
import { createClient } from 'graphql-ws';

@NgModule({ exports: [ApolloModule], providers: [ { provide: APOLLO_OPTIONS, useFactory(httpLink: HttpLink): ApolloClientOptions { // Create an http link: const http = httpLink.create({ uri: 'http://localhost:3000/graphql', }); // Create a websocket link: const ws = new GraphQLWsLink( createClient({ url: 'ws://localhost:8420/graphql', }), );

            // using the ability to split links, you can send data to each link
            // depending on what kind of operation is being sent
            const link = split(
                ({ query }) => {
                    const call = getMainDefinition(query);
                    console.log('GraphQL call > ', call);
                    return (call.kind === 'OperationDefinition' && call.operation === 'subscription');
                },
                ws,
                http,
            );

            return { link, cache: new InMemoryCache(), };
        },
        deps: [HttpLink],
    },
],

}) export class GraphQLModule { }


> **mysubscriptiongql.ts**

import { Injectable } from '@angular/core'; import { gql, Subscription } from 'apollo-angular';

@Injectable({ providedIn: 'root', }) export class MySubscriptionGQL extends Subscription { document = gql subscription { msg } ; }


> **sample.component.ts**

import { Component, OnInit, ViewEncapsulation } from '@angular/core'; import { Apollo, gql } from 'apollo-angular'; import { MySubscriptionGQL } from './mysubscriptiongql';

@Component({}) export class SampleComponent implements OnInit {

constructor(private apollo: Apollo, private mySubscriptionGQL: MySubscriptionGQL) { }

ngOnInit(): void {
    // 1. using apollo client directly
    this.apollo.subscribe({
        query: gql`subscription { msg }`,
    }).subscribe((result) => {
        console.log('apollo-client', result);
    });

    // 2. using apollo-angular Subscription definition
    this.mySubscriptionGQL.subscribe().subscribe((result) => {
        console.log('subscription-gql', result);
    });
}

}

inpercima commented 2 years ago

Hi @neaplus, thanks for your work. I searched for a solution to get subscriptions within graphql-ws to work but many possible solutions failed.

Unfortunately, I can't get your solution activated either. I created a demo project with a graphql module, located at https://github.com/inpercima/tester-playground/blob/main/angular-nestjs-apollo-graphql/frontend/src/app/module/graphql.module.ts#L27.

If I use graphql-ws the subscription is canceled with: Socket closed with event 1002.

So in my example I tested it with a switch to check the behaviour. Can you tell me what I do wrong?

neaplus commented 2 years ago

Hey @inpercima, thanks. I checked and your angular app seems totally fine but the issue occurs due to backend imo. I got same error against your endpoint via postman too.

Screen Shot 2022-08-02 at 15 34 37

.

inpercima commented 2 years ago

Hey @neaplus thank you for your response. First I found a issue on my site. I used ws instead of wss but it was working, I don't know why, okay. I tested it online with https://eat.bananacakepop.com/ with following options and it looks like it is working: grafik

And you are right, I tested it with postmans Websocket BETA too and I got the same error. Does Postman uses the correct sub protocol?

In bananacakepop, you can see it on the picture, I can choose the Subscription Protocol. I used Apollo, but there I can change it to GraphQL which will not work. Maybe postman us it too?

inpercima commented 2 years ago

In further tests I used a non public endpoint in my company an there was the same result.

If I use graphql-ws the conneection doesn't work, if I use subscriptions-transport-ws, it works. So I think something in the library is not well configured.

Do someone has another public subscription endpoint I can test?

KeithGillette commented 2 years ago

@inpercima — Have you upgraded your server endpoints to use graphql-ws, as well? Per the project's disclaimer, graphql-ws is not cross-compatible with subscriptions-transport-ws and both the client and server must use the same GraphQL over WebSocket Protocol.

inpercima commented 2 years ago

@KeithGillette Thanks for your response. The Server is an .NET-Application using "Hot Chocolate" with Apollo, see: https://chillicream.com/docs/hotchocolate.

But this seems a good question. I found some issues with "Hot Chocolate". Maybe this could be a version problem. I will check this and comment later.

inpercima commented 2 years ago

Hey @KeithGillette and @neaplus Based on your answers, we were able to narrow down the problem and now also solve it. It was right, the backend server did not had the correct version. We use "Hot Chocolate" in version 12 but in tihs version the subscriptions are not fully activated. So the error accurs. They work on a new version in which the graphql-ws library is fully included. We checked this with a preview version an it works.

Thank you very much for your help. :100:

Here some links referenced: https://stackoverflow.com/questions/72115080/subscription-doesnt-work-with-apollo-client-and-hot-chocolate-net-core-web-api https://github.com/ChilliCream/hotchocolate/issues/3758