DEV Community

Cover image for 5 Minute Tutorial: Easily Get Base Types with AWS Amplify GraphQL Codegen for TypeScript
Stephen A. Lizcano
Stephen A. Lizcano

Posted on • Updated on

5 Minute Tutorial: Easily Get Base Types with AWS Amplify GraphQL Codegen for TypeScript

This short walkthrough illustrates how you can easily extend or generate your base Types for your TypeScript application easily using the AWS Ampligy/Apollo GraphQL codegen.

Note, you should be slightly familiar with GraphQL and Apollo or AWS Amplify GraphQL services, and the basics of TypeScript

Why are base types important?

Base types, and specifically using TypeScript with the code generator allows us to make sure that the types we are creating, updating, or listing from our GraphQL api conform to our schema.

This is especially important when designing our API function calls, so that everything we submit is of the correct shape and format, preventing us from dealing with errors later that could take a long time to debug.

I work in Healthcare, specifically making web and mobile applications for physicians and administrators.

So, we're going to use a simple healthcare focused schema to illustrate the example using medications and interactions.

Schema:

# schema.graphql

# @model automatically generates api calls for our API using GraphQL, AppSync & DynamoDB

type Patient @model {
  # basic patient information
  id: ID!
  name: String!
  sex: String!

  encounters: [Encounter] @connection(name: "Encounters")
}

type Encounter @model {
  # when a patient sees a doctor, that's an Encounter
  id: ID!
  reason: String!
  patient: Patient @connection(name: "Encounters")
  orders: [Order] @connection(name: "EncounterOrders")
}

type Order @model {
  # For lab tests like xrays, MRI, etc
  id: ID!
  order: String!
  # Tie the order to the encounter/patient visit it was created on
  Encounter: Encounter @connection(name: "EncounterOrders")
}

This is a basic one-to-many schema, that models a patient, an encounter with a physician, and sample clinical orders that can be made.

To generate your API, use apollo or amplify GraphQL codegen using:


$ amplify codegen

Follow the walkthrough, and be sure to select TypeScript for your code generation language.

You'll have a filed called API.ts generated, most likely in your ./src folder if you're using React, React Native, etc.

Open API.ts where you saved it, and look for the type GetPatientQuery:


export type GetPatientQuery = {
  getPatient:  {
    __typename: "Patient",
    id: string,
    name: string,
    sex: string,
    encounters:  {
      __typename: "ModelEncounterConnection",
      items:  Array< {
        __typename: "Encounter",
        id: string,
        reason: string,
      } | null > | null,
      nextToken: string | null,
    } | null,
  } | null,
};

How do we extract the Patient base type?

By utilizing TypeScripts Utility types to transform these types into the types all of our projects can use.

We need to remove the possible nullish return of the API call, and any unnecessary annotations.


export interface Patient
  extends Omit<Exclude<GetPatientQuery["getPatient"], null>, "__typename"> {}

That's it!

What's happening here is the Exclude utility type is removing/excluding the "null" of the type, which exists in case no data is returned/found.

Next, the Omit utility type removes the "__typename" label that is generated by the codegen to tell us the base type name.

That's it!

We can now use Patient as a base type for usage in our React/Vue/Angular etc web apps. We have the types for mapping, adding, and deleting types.

We can extend this to all of the other types that we created in the Schema, too.

And they automatically update if we change our schema!

Cheers, and hope this was helpful!

Need help with Amplify, cloud, or full-stack? I'm available for consulting.

Top comments (2)

Collapse
 
rpainter8west profile image
Russ Painter • Edited

I found I had to also exclude "undefined".

export type DomainModel = Omit<Exclude<APIt.GetDomainQuery["getDomain"], null | undefined>, "__typename">;
Enter fullscreen mode Exit fullscreen mode
Collapse
 
dantasfiles profile image
Daniel S. Dantas

I refer to your technique in Using Typescript with AWS Amplify API