Skip to content

Strategy for @client directive #366

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
asci opened this issue Jan 23, 2018 · 26 comments
Closed

Strategy for @client directive #366

asci opened this issue Jan 23, 2018 · 26 comments

Comments

@asci
Copy link

asci commented Jan 23, 2018

Hello!

What would be the strategy for @client directive? Just ignore the whole file or ignore only a client part?

Thanks

@0xcaff
Copy link
Contributor

0xcaff commented Jan 27, 2018

Duplicate of #275 ?

@vic08
Copy link

vic08 commented Feb 19, 2018

I'm also curious, what will be the way to handle @client directive in queries. I'm planning to manage client state with apollo but no way to generate types, when I use @client directive in the query

@kohlikohl
Copy link

Right now, having a @client directive in the query generates an error when the field that has been tagged with it is not in the schema.
It kind of makes sense that the field is not in the server-schema but maybe having the ability to feed multiple schemas (client and server schema etc) to codegen, which merges them and uses the result to validate the query would be useful.

Similar to what merge-graphql-schemas does but with the difference that all types are merged together.

@majelbstoat
Copy link

majelbstoat commented Feb 22, 2018

It would be great to not have to exclude the whole file, as one of the promises of apollo-link-state is that you can get client-cached and remote data all in one query (once apollographql/apollo-link-state#140 is fixed, at least). Plus, it would be good to have type-safety on even those local client operations.

Having those client fields at least set to any would be at least a useful start though.

@majelbstoat
Copy link

majelbstoat commented Feb 26, 2018

@kohlikohl, given that Urigo/merge-graphql-schemas#118 has been merged, do you mind sharing how you made this all work for @client directives? What did you merge together to make codegen understand the directive? Do you literally define the client-side types, Query, and Mutation in a separate file, merge them with the server ones using merge-graphql-schema, and then pass that output to codegen?

@kohlikohl
Copy link

@majelbstoat This is exactly what I am doing.

@martijnwalraven
Copy link
Contributor

If anyone wants to work on incorporating a solution for this in apollo-codegen, contributions are very welcome!

@fbartho
Copy link

fbartho commented Feb 28, 2018

I'm currently pre-processing my queries to strip the @client and @rest directives, and then using code-gen to make my TypeScript types. It's working fine, but irritating that I have to strip the directives myself.

@justinmakaila
Copy link

Working on an extension for the graphql-cli-codgen tool to do just this. It uses the generate function under the hood. Most of the heavy lifting comes from the merge-graphql-schemas repo mentioned above.

@zhenwenc
Copy link

I wrote a small script to merge the remote GraphQL schema with my apollo-link-state local/client schemas, not sure if its the right way though. Hope it helps anyone.

@majelbstoat
Copy link

@zhenwenc's script worked perfectly for me. I created a clientSchema.graphql that defined the Queries and Mutations which use @client, pointed the script at that and my remote server, and it worked first time! I haven't looked at apollo-codegen's internals enough to know whether it would be a simple patch, but the approach works well. Thank you @zhenwenc!

@nihaux
Copy link

nihaux commented Apr 30, 2018

@zhenwenc thx for the snippet worked for me too 👍
Though I had to change line 79 for:
const typeDefs = mergeTypes([remoteSchema, ...clientSchemas], { all: true });
(the all: true param)

@nilshartmann
Copy link
Contributor

@zhenwenc Thanks for your script, works perfect

As @nihaux mentioned, it's necessary to add { all: true } when you "extend" types from your server schema with new fields on the client, ie:

Person defined on server schema:

type Person {
  name: String
  dateOfBirth: Date!
}

Add agefield on the client schema:

type Person {
  age: Int!
}

Setting all: true on the mergeTypes call, merge-graphql-schemas actually merges both declarations into one type. Otherwise merge-graphql-schemas would fail (Type "Person" was defined more than once.)

@zhenwenc
Copy link

zhenwenc commented May 6, 2018

Thanks @nihaux and @nilshartmann for pointing out the issue. 👍
I have updated the script. Cheers!

@hanming2033
Copy link

hanming2033 commented May 22, 2018

@zhenwenc saved my life man!!!

@shadaj
Copy link
Contributor

shadaj commented Jul 6, 2018

Exciting update to share, we are working on official support for the @client directive at apollographql/rover#480!

@shadaj
Copy link
Contributor

shadaj commented Jul 10, 2018

Support for the @client directive with client-side schemas has been released with Apollo CLI 1.4.0!

@shadaj shadaj closed this as completed Jul 10, 2018
@greatwitenorth
Copy link

Is there a complete example where the schema is downloaded from the remote graphql server, combined with the local state, then generate the type definition files? I cannot seem to get this working (using apollo cli version 1.7.0)

@danielwong2268
Copy link

Any documentation around how to do this would be helpful. I'm also having issues getting this to work.

@vadistic
Copy link

vadistic commented Sep 18, 2018

I needed to generate typings for local state & remote queries.

After few unproductive hours with errors like:
→ Validation of GraphQL query document failed
→ Cannot read property 'extends' of undefined

Or trying to merge schema like in gist above and getting:
→ Type "Query" already exists in the schema. It cannot also be defined in this type definition.

I could not even recreate unit tests and then with rage I deleted apollo.config.js and suddenly everything works^^

My guess is that apollo-cli cannot read clientSchema from config and does not try to read it from flag when schema is defined in config, ugh. Some error clue, that clientSchema is undefined or smth would really be nice.

@greatwitenorth @danielwong2268 try it!


Example based on unit tests for anyone in need

  • Delete your apollo.config.js ^^
# src/state/schema.graphql

extend type Query { # needs to extend if type exists server-side
  localState: String!
  complexLocalState: LocalType!
}

type LocalType {
  someData: String!
}

  • Define some queries on some components
// src/components/SomeComponent.tsx

const GET_STUFF= gql`
  # some server query
  query SimpleQuery {
    users {
      id
    }
  
  # and some local
    localState @client

    complexLocalState @client {
      someData
    }
  }
`
  • Download schema with apollo schema:download

  • And hit

$ apollo codegen:generate generated \
   --queries=src/components/**/*.tsx \
   --target typescript \
   --schema src/generated/schema.json \ 
   --clientSchema src/state/schema.graphql

I'm so happy, that it works 🙃

@kyledetella
Copy link

@vadistic thank you for that!. I hit the same issue yesterday and was blocked by it this morning. I agree that some better error messaging would be helpful here.

I may work on a PR to help with that (and maybe some docs too).

@chaffeqa
Copy link

For anyone else running into this issue, I had x2 problems:

  1. Make sure the client schema is a .graphql file (not template literal in a .js/.ts file)
  2. Make sure to use the extends type Mutation/Query (note the extends)

@bsunderhus
Copy link

In [email protected] I'm receiving

Unexpected argument: --clientSchema=src/config/schema.graphql`

While trying apollo client:codegen __generated --target typescript --clientSchema=src/config/schema.graphql

Did the argument change?

I was looking into the codegen there's actually no argument to pass local schema. Has this been updated and removed somehow?

I'm still not sure how this extend keyword works also. Doe anyone has a complete working example

@ZenSoftware
Copy link

@bsunderhus Since apollo v2, a client schema does not need to be explicitly defined anymore. It should be evaluated appropriately if it is part of the --queries=... glob.

See this issue: #696 (comment)

@bsunderhus
Copy link

I've noticed. I actually ended up opening the issue #731 just for this, and once I've finally found this information I immediately closed it! Totally forgot about commenting here, sorry @ZenSoftware

@bsunderhus
Copy link

Oh and actually, I'm using a query to get only .ts files and still the codegen manages to find my .graphql files with no problem at all. They do not depend on the query apparently, I don't know if that's the right behavior.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests