Extending generated graphql type and resolver

Hi, I am trying to keep separated the files that rw generates and my own custom types and resolvers.
My question is:
I want to add a field to a generated type,
In my case for example I am managing some subscription options for the user to join an online service, so I have

// api/src/graphql/subscriptionTypes.sdl.ts
type SubscriptionType {
    id: Int!
    status: String!
    date_created: DateTime
    date_updated: DateTime
    slug: String
    cycle_length: Int!
    cycle_period: String
    price: Float!
    subscription_types_translations: [SubscriptionTypeTranslation]!
    user_subscriptions: [UserSubscription]!
  }

 type Query {
    subscriptionTypes: [SubscriptionType!]! @requireAuth
    subscriptionType(id: Int!): SubscriptionType @requireAuth
  }

the subscription type translation is a related table where I hold language specific strings, the model is like this


model SubscriptionType {
  id                              Int                           @id @default(autoincrement())
  status                          String                        @default("draft") @db.VarChar(255)
  ...
  price                           Decimal                       @db.Decimal(4, 2)
  subscription_types_translations SubscriptionTypeTranslation[]
  user_subscriptions              UserSubscription[]
}

model SubscriptionTypeTranslation {
  id                    Int               @id @default(autoincrement())
  subscription_types_id Int?
  languages_id          String?           @db.VarChar(255)
  name                  String?           @db.VarChar(255)
  description           String?
  languages             Language?         @relation(fields: [languages_id], references: [code], onUpdate: NoAction, map: "subscription_types_translations_languages_id_foreign")
  subscription_types    SubscriptionType? @relation(fields: [subscription_types_id], references: [id], onUpdate: NoAction, map: "subscription_types_translations_subscripti__2a003d1d_foreign")
}

The service for subscriptionTypes has this:


//api/src/services/subscriptionTypes/subscriptionTypes.ts
export const SubscriptionType: SubscriptionTypeRelationResolvers = {
  subscription_types_translations: (_obj, { root }) => {
    return db.subscriptionType
      .findUnique({ where: { id: root?.id } })
      .subscription_types_translations()
  },
  user_subscriptions: (_obj, { root }) => {
    return db.subscriptionType
      .findUnique({ where: { id: root?.id } })
      .user_subscriptions()
  },
}

Now I would like to be able to add a way for the subscriptionTypes query to just loaded the translations for a given language,

I noticed that I can just add a .sdl.ts file with the same type name and just add fields and they will get merged. So if I add:


// api/src/graphql/subscriptionTypesExtras.sdl.ts
export const schema = gql`
  type SubscriptionType {
    subscription_types_translation: SubscriptionTypeTranslation
  }

this new field gets merged into the type.
But now how do I add a resolver for this field?
Normally I would edit the relation resolver

//api/src/services/subscriptionTypes/subscriptionTypes.ts
export const SubscriptionType: SubscriptionTypeRelationResolvers = {
  subscription_types_translations: (_obj, { root }) => {
    return db.subscriptionType
      .findUnique({ where: { id: root?.id } })
      .subscription_types_translations()
  },
subscription_types_translation: (_obj, { root }) => {
    ...add my code here
  },
  user_subscriptions: (_obj, { root }) => {
    return db.subscriptionType
      .findUnique({ where: { id: root?.id } })
      .user_subscriptions()
  },
}

but then this file would be overwritten if I needed to regenerate the sdl for any reason.

Is there a way to get around this problem?

Thanks so much in advance

RW generators don’t handle all edge cases. As an example from the RW CLI docs for yarn rw generate sdl <model>:

The sdl will inspect your schema.prisma and will do its best with relations. Schema to generators isn’t one-to-one yet (and might never be).

But you can add custom generators (including for services). You should be able to extend the existing template with your added method.

1 Like