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 GraphQLtypeandinput, enums for GraphQLenum)- make_operation! — generates the
Operationenum 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 detailsname_override— see section below for detailsdefault_traits— see section below for detailsderive— 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::Serializemust be implemented on any type used as a return type of a Query or Mutation operation.serde::Deserializemust be implemented on anyinputtype 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
typeandinput):Debug,Clone,Serialize,Deserialize - Enums (GraphQL
enum):Debug,Clone,Copy,Serialize,Deserialize,PartialEq,Eq,PartialOrd,Ord,Hash,DisplayandFromStr
§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: Defaultderive = 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 variantsconst fn all() -> [Self; Self::COUNT]— array of all variantsconst fn index(self) -> usize— index of the variant (useful for array indexing)Displayimpl (whendefault_traitsistrue, displays the original GraphQL name)FromStrimpl (whendefault_traitsistrue, parses from the original GraphQL name)
§GraphQL to Rust Type Mapping
| GraphQL | Rust |
|---|---|
String | String |
ID | lambda_appsync::ID |
Int | i32 |
Float | f64 |
Boolean | bool |
AWSEmail | lambda_appsync::AWSEmail |
AWSPhone | lambda_appsync::AWSPhone |
AWSTimestamp | lambda_appsync::AWSTimestamp |
AWSDate | lambda_appsync::AWSDate |
AWSTime | lambda_appsync::AWSTime |
AWSDateTime | lambda_appsync::AWSDateTime |
AWSJSON | serde_json::Value |
AWSURL | lambda_appsync::AWSUrl |
AWSIPAddress | core::net::IpAddr |
[T] (list) | Vec<T> |
| nullable | Option<T> |
| Custom type | The 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.rsWhen 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.