-
Notifications
You must be signed in to change notification settings - Fork 56
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
How to handle overrides when importing? #203
Comments
Can you still reproduce this with |
@marktani I'm not 100% certain if I can or can't... One of the reasons for me moving to an Apollo Server 2.0 was to better organise my code, create a more modular based structure. I've had it working in |
So as a bit of extra information, it all seems to work fine if I do the following:
Resulting in: # import List from './generated/prisma.graphql'
# import ListItem from './generated/prisma.graphql'
# import Menu from './generated/prisma.graphql'
# import OpeningHours from './generated/prisma.graphql'
# import Tag from './generated/prisma.graphql'
# import VenueWhereInput, VenueOrderByInput from './generated/prisma.graphql'
# import Zone from './generated/prisma.graphql'
type User {
id: ID!
activities: [ActivityEvent!]!
areas: [Area!]
email: String
firstName: String
following: [User!]
followedLists: [List!]
fullName: String
username: String
lastName: String
lists: [List!]
location: String
metadata: Json
profileImage: String
tags: [Tag!]!
zones: [Zone!]!
}
type Venue {
id: ID!
name: String!
shortDescription: String!
longDescription: String!
images: [String!]!
latitude: Float!
longitude: Float!
addressLine1: String!
addressLine2: String!
addressCity: String!
postcode: String!
zone: Zone!
tags: [Tag!]!
contactNumber: String!
pdfMenus: [Menu!]!
lists: [List!]!
listItems: [ListItem!]!
instagramHandle: String!
bookingUrl: String!
bookingType: String!
wifiSSID: String!
wifiPassword: String!
openingHours: OpeningHours!
published: Boolean!
} But, this is the key bit... This exactly what I was trying to avoid. I hate having to define all my types in one big I think that there is some magic going on with Clearly that won't work with the way the code is structured ( |
I added a test case for collision in GraphQL import. That part looks to be working as expected. |
But I think you want to merge imported type with type defined in JS/TS. Let me get back to you on this. |
@divyenduz yes, that's precisely my use-case. It's all about how to combine the use of I appreciate it's not really a |
@Siyfion : Noted, this can happen via some additional tooling exposed by I remember that you tried |
If I'm completely honest, I got a little worried when it started trying to merge two different root |
@marktani & others After a lot of discussion & help from @divyenduz, I think I've got somewhere close to a workable solution! In short, if you want to keep your GraphQL in JS and modular, you need to convert it back to SDL, merge it all together, add any // Convert the typeDefs BACK to SDL from objects
const schemaSDLArray = typeDefs.map(typeDef => print(typeDef))
// Push the imports as a simple string to the top of the array
schemaSDLArray.unshift(imports)
// Merge the array into one big SDL "file"
const schemaSDL = schemaSDLArray.join('\n')
// Run the SDL through importSchema, so that the dependencies are imported
const withImportsSDL = importSchema(schemaSDL) I've updated my branch to now have the new code in it, with the main commit being: https://github.com/Siyfion/node-graphql-starter/commit/7adaca411161a1e93bf356a8de051d50e2bd163c However, I have uncovered an issue with |
The issue with This is now a blocker to getting this issue resolved unfortunately. |
@divyenduz I actually don’t think that the "support” I’m requiring should be a very big change at all… Perhaps it wasn’t fully explained? I don’t need
at the moment the The |
hey @Siyfion I had the same issue and used a more "manual" method to import types that I need: import * as fs from 'fs'
import * as path from 'path'
import { gql } from 'apollo-server-express'
const prismaDefs = gql(
fs.readFileSync(
path.resolve(path.join(__dirname), '../generated/prisma.graphql'),
'utf8',
),
)
export const importPrismaDefs = (namesToImport: string[]) => {
const definitions: any[] = prismaDefs.definitions
.filter((definition: any) => {
if (definition.name) {
return namesToImport.includes(definition.name.value)
}
return false
})
return {
...prismaDefs,
definitions,
}
} I used this function to import all "inputs" that I didn't want to recreate like So I use you logic which works well! |
Hey @johannpinson Thats a pretty neat way to do it! I haven't found a way to use How does your strategy cope with "overrides"? I guess that as you are importing things entirely manually, you just don't import them and then redefine them in your schema? Are you using GraphQL in JS ( |
Finally I also use const baseTypes = gql`
# Original queries, mutations, types and input that I need for my server
...
`
const extendedTypes = gql`
extend type User {
test: String
}
`
-----
import { baseTypes, extendedTypes } from './types'
// Convert the typeDefs BACK to SDL from objects
const schemaSDLArray: string[] = [print(baseTypes)]
// Push the imports as a simple string to the top of the array
schemaSDLArray.unshift(imports)
// Merge the array into one big SDL "file"
const schemaSDL: string = schemaSDLArray.join('\n')
// Run the SDL through importSchema, so that the dependencies are imported
const baseTypeDefs: DocumentNode = gql(importSchema(schemaSDL))
// Merge all differents types
const typeDefs = [baseTypeDefs, extendedTypes] And it looks to work 😄(and yes I know, the Like you see, I use too the apollo-tag (aka By the way, the extends that I use a really simple for the moment like add a field into a type or an input. |
That code looks familiar @johannpinson! 😉 I may well have a play with your approach later on tonight, or early next week. I feel like you might have cracked the final piece of the puzzle! 👍 Do you have a repo with all this as a working example? |
Ha ah, sure @Siyfion! After I not sure it the "perfect" final piece, because we use The only example I have it the project on which I work for a client, so I will try to create a demo asap (because I will be on vacation few days from tomorrow). |
Hey @johannpinson I've been trying things out with your method, and I've got it all working... The good news is that your block:
no longer needs to exist! You just need to merge all your arrays of |
Latest (working) code now available here: |
Hello @Siyfion After it depends how you want to manage the imports of external types :
One perfect solution which be that |
Yeah, I prefer the explicit import syntax, as if your GraphQL Playground endpoint is exposed publicly, they don't get to see the internal workings of your entire DB structure, which the automatically imported Prisma types/imports, etc. all give away a bit! |
Yes I see but it forces me to have all this import for one type created for example: const TypeImportedFromPrisma = importPrismaDefs([
// Top-level requested type by previous declarations
'SpaceCreateInput',
'SpaceUpdateInput',
'SpaceWhereUniqueInput',
// Inherit requested type
// For 'SpaceCreateInput'
'StoryCreateManyWithoutSpaceInput',
'StoryCreateWithoutSpaceInput',
'StoryWhereUniqueInput',
'StoryCreateimagesInput',
'UserCreateOneWithoutSpacesInput',
'UserCreateWithoutSpacesInput',
'UserWhereUniqueInput',
// For 'SpaceUpdateInput'
'StoryUpdateManyWithoutSpaceInput',
'StoryUpdateWithWhereUniqueWithoutSpaceInput',
'StoryUpsertWithWhereUniqueWithoutSpaceInput',
'StoryUpdateWithoutSpaceDataInput',
'StoryUpdateimagesInput',
'UserUpdateOneWithoutSpacesInput',
'UserUpdateWithoutSpacesDataInput',
'UserUpsertWithoutSpacesInput',
]) and my final model will have around a twenty type which can have relation between them 😆 |
True, I could argue that exposing We don't expose any Prisma types for any mutations. They don't allow us to give the level of control that we needed. |
Yes all mutations (and some queries/fields) will be cover by On your side, you will "rewrite" all input and remove "connect"-like field available from Prisma? |
Few months ago I got so frustrated with exactly all this, that I made a tool. Weird that I did not notice this issue before. Frankly - right now I'm more partial to interpolated string literals in ts, but I'm plugging this as some curiosity: https://github.com/vadistic/graphql-override It even integrates with prisma config (and works) |
Firstly, I have an example reproduction of the issue I'm facing available here: https://github.com/Siyfion/node-graphql-starter/tree/graphql-import
So what I'm trying to do, is get my Prisma generated schema imported into my Apollo Server 2.0 project. It works fine doing it the way I am, until I re-define a type that's indirectly being imported with
graphql-import
.Clearly I need a way of merging the schema and when encountering duplicates, using the ones defined in my code over the imported ones, but I can't seem to figure out a way to do this?
FYI the error in the example repo is:
Error: Type "User" was defined more than once.
This is due to me having defined a custom type for User that adds a
fullname
field to the original schema.The text was updated successfully, but these errors were encountered: