Skip to main content

make_types

Macro make_types 

Source
make_types!() { /* proc-macro */ }
Expand description

Generates Rust types (structs and enums) from a GraphQL schema file.

§Usage

make_types!("path/to/schema.graphql");

// or with options:
make_types!(
    "path/to/schema.graphql",
    type_override = Type.field: CustomType,               // override a field type
    name_override = TypeName: NewTypeName,                // rename a type
    name_override = Type.field: new_field_name,           // rename a field
    name_override = Enum.VARIANT: NewVariant,             // rename an enum variant
    default_traits = MyType: false,                       // disable default traits for a type
    derive = MyType: Default,                             // add an extra derive macro to a type
    derive = MyType: PartialEq,                           // (specify multiple times for multiple derives)
);

This is one of three composable macros that together replace the monolithic [appsync_lambda_main!]:

  • make_types! — generates types (structs for GraphQL type and input, enums for GraphQL enum)
  • make_operation! — generates the Operation enum and dispatch logic
  • make_handlers! — generates the Lambda handler trait

make_appsync! is a convenience macro that combines all three.

§Schema Path Argument

The first argument to this macro must be a string literal containing the path to your GraphQL schema file. The schema path can be:

  • An absolute filesystem path (e.g. “/home/user/project/schema.graphql”)
  • A relative path, that will be relative to your crate’s root directory (e.g. “schema.graphql”, “graphql/schema.gql”)
  • When in a workspace context, the relative path will be relative to the workspace root directory

§Options

  • type_override — see section below for details
  • name_override — see section below for details
  • default_traits — see section below for details
  • derive — see section below for details

§Type Overrides

The type_override option allows overriding the Rust type generated for a struct field:

  • type_override = Type.field: CustomType

These overrides are only for the Rust code and must be compatible for serialization/deserialization purposes, i.e. you can use String for a GraphQL ID but you cannot use a u32 for a GraphQL Float.

Note: operation-level overrides (Query.op: Type or Query.op.arg: Type) are not relevant here since make_types! does not generate operation types. Use make_operation! or make_appsync! for those.

§Name Overrides

The name_override option supports renaming various schema elements:

  • Type/input/enum names: name_override = TypeName: NewTypeName
  • Field names: name_override = Type.field: new_field_name
  • Enum variants: name_override = Enum.VARIANT: NewVariant

These overrides are only for the Rust code and will not change serialization/deserialization, i.e. serde will rename to the original GraphQL schema name.

Note that when using name_override, the macro does not automatically change the case: you are responsible to provide the appropriate casing or Clippy will complain.

§Default Traits

The default_traits option controls whether the macro applies its default set of traits on a given type:

  • default_traits = TypeName: bool

The default value is true. When set to false for a type, none of the default traits are implemented for that type, giving you the opportunity to implement them yourself.

Important: certain traits are required by the generated operation dispatch code regardless of this setting:

  • serde::Serialize must be implemented on any type used as a return type of a Query or Mutation operation.
  • serde::Deserialize must be implemented on any input type used as an operation argument.

You are free to disable the default implementations, but you must provide alternative ones — whether via derive entries, manual impl blocks, or any other means.

The default traits are:

  • Structs (GraphQL type and input): Debug, Clone, Serialize, Deserialize
  • Enums (GraphQL enum): Debug, Clone, Copy, Serialize, Deserialize, PartialEq, Eq, PartialOrd, Ord, Hash, Display and FromStr

§Additional Derive Macros

The derive option allows adding an extra derive macro on top of the default ones for a given type:

  • derive = TypeName: Trait

Each derive entry adds a single trait. Specify the option multiple times to add several traits:

  • derive = Player: Default
  • derive = Player: PartialEq

This is additive: it does not replace the default traits (unless default_traits is set to false for the same type, in which case only the explicitly listed traits are derived).

This is useful for deriving traits that the macro does not provide, such as Default on a struct or PartialEq.

For enums, derive = MyEnum: Default is supported: the first variant declared in the GraphQL schema becomes the default value.

§What Gets Generated

For each GraphQL type (excluding Query, Mutation, and Subscription), with default traits:

#[derive(Debug, Clone, Serialize, Deserialize)]

#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct TypeName {
    pub field1: FieldType,
    pub field2: Option<FieldType>,
    // ...
}

For each GraphQL input, with default traits:

#[derive(Debug, Clone, Serialize, Deserialize)]

#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct InputName {
    pub field1: FieldType,
    // ...
}

For each GraphQL enum, with default traits:


#[derive(Debug, Clone, Copy, Serialize, Deserialize, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub enum EnumName {
    Variant1,
    Variant2,
    // ...
}

Each generated enum also gets:

  • const COUNT: usize — number of variants
  • const fn all() -> [Self; Self::COUNT] — array of all variants
  • const fn index(self) -> usize — index of the variant (useful for array indexing)
  • Display impl (when default_traits is true, displays the original GraphQL name)
  • FromStr impl (when default_traits is true, parses from the original GraphQL name)

§GraphQL to Rust Type Mapping

GraphQLRust
StringString
IDlambda_appsync::ID
Inti32
Floatf64
Booleanbool
AWSEmaillambda_appsync::AWSEmail
AWSPhonelambda_appsync::AWSPhone
AWSTimestamplambda_appsync::AWSTimestamp
AWSDatelambda_appsync::AWSDate
AWSTimelambda_appsync::AWSTime
AWSDateTimelambda_appsync::AWSDateTime
AWSJSONserde_json::Value
AWSURLlambda_appsync::AWSUrl
AWSIPAddresscore::net::IpAddr
[T] (list)Vec<T>
nullableOption<T>
Custom typeThe generated Rust struct/enum

§Use Case: Shared Types Crate

The primary use case for make_types! alone (vs make_appsync!) is when you want to share GraphQL types across multiple crates — e.g., a shared library crate for types and separate binary crates for different Lambda functions:

my-project/
├── schema.graphql
├── shared-types/     # lib crate using make_types!
│   └── src/lib.rs
├── lambda-a/         # bin crate using make_operation! + make_handlers!
│   └── src/main.rs
└── lambda-b/         # another bin crate
    └── src/main.rs

When using name_override with make_types! in a multi-crate setup, you must use the same overrides in make_operation! so that operation signatures reference the correct renamed types.

§Examples

§Basic usage:

lambda_appsync::make_types!("schema.graphql");

§With type overrides:

lambda_appsync::make_types!(
    "schema.graphql",
    // Use String instead of the default lambda_appsync::ID
    type_override = Player.id: String,
);

§With name overrides:

lambda_appsync::make_types!(
    "schema.graphql",
    // Rename the Player struct
    name_override = Player: GqlPlayer,
    // Rename a field
    name_override = Player.name: email,
    // Rename an enum variant
    name_override = Team.PYTHON: Snake,
);

§Combined overrides:

lambda_appsync::make_types!(
    "schema.graphql",
    type_override = Player.id: String,
    name_override = Player: GqlPlayer,
);

§Disable default derivations for a type:

lambda_appsync::make_types!(
    "schema.graphql",
    // Player will have no derive macros — implement them yourself
    default_traits = Player: false,
);

§Add extra derive macros to a type:

lambda_appsync::make_types!(
    "schema.graphql",
    // Add Default and PartialEq on top of the default derives
    derive = Team: Default,
    derive = Player: Default,
    derive = Player: PartialEq,
);

§Combine default_traits and derive:

lambda_appsync::make_types!(
    "schema.graphql",
    derive = Team: Default,
    // Disable defaults and provide only the derives you need
    default_traits = Player: false,
    derive = Player: Debug,
    derive = Player: Default,
);

This macro generates only types (structs and enums). It does not generate the Operation enum or Lambda handler code. Use make_operation! for operations and make_handlers! for the handler, or make_appsync! for all three at once.