Skip to content

Proper Way to Organize Schema File

0

Good afternoon.

I am building out a new project using Amplify Gen2. So far things are going ok, hitting a few road blocks here and there. I do have a design question.

My schema file is probably going to get pretty big with different schemas and functions (please see below) I already figured out how to abstract the schema_n entries, but what would be a good way to take care of the different authorizations?

I may have someservice_1, .... someservice_n and I don't want n - entries in the authorization section.

If I remove someservice_1 ... someservice_n from the authorization section, I run the risk of the following error:

Argument of type 'LambdaProvidedEnvVars' is not assignable to parameter of type 'DataClientEnv'. Property 'AMPLIFY_DATA_DEFAULT_NAME' is missing in type 'LambdaProvidedEnvVars' but required in type '{ AWS_ACCESS_KEY_ID: string; AWS_SECRET_ACCESS_KEY: string; AWS_SESSION_TOKEN: string; AWS_REGION: string; AMPLIFY_DATA_DEFAULT_NAME: string; }'.

await getAmplifyDataClientConfig(env);

const schema = a
  .schema({

    schema_1: a
      .model({
        // fields...
      })
      .authorization((allow) => [allow.publicApiKey()]),

    .....

    schema_n:
        // fields...
      })
      .authorization((allow) => [allow.publicApiKey()]),

    someservice_1: a
      .mutation()
      .arguments({
          // fields
      })
      .returns(a.ref("Group"))
      .handler(a.handler.function(someservice))
      .authorization((allow) => [allow.publicApiKey(), allow.authenticated()]),

    someservice_n: a
      .mutation()
      .arguments({
          // fields
      })
      .returns(a.ref("Group"))
      .handler(a.handler.function(someservice))
      .authorization((allow) => [allow.publicApiKey(), allow.authenticated()]),
  }}
  .authorization((allow) => [
    allow.resource(someservice_1),
    allow.resource(someservice_n),
    allow.publicApiKey(),
    allow.authenticated(),
  ]);
asked 11 hours ago4 views
1 Answer
0

When organizing a large schema file in Amplify Gen 2, there are several approaches you can take to make it more maintainable.

For handling multiple authorization rules across different services and models, you can:

  1. Split your schema into multiple files: Create separate files for different logical groups of models and import them into your main schema file. This helps with organization and readability.

  2. Create reusable authorization functions: Define common authorization patterns as variables or functions that you can reuse across your schema:

// Define reusable auth patterns
const publicAndAuthenticatedAccess = (allow) => [
allow.publicApiKey(),
allow.authenticated()
];

const ownerOnlyAccess = (allow) => [
allow.owner()
];

// Then use them in your schema
const schema = a.schema({
schema_1: a
.model({
// fields...
})
.authorization(publicAndAuthenticatedAccess),

schema_2: a
.model({
// fields...
})
.authorization(ownerOnlyAccess),

someservice: a
.mutation()
.arguments({
// fields
})
.returns(a.ref("Group"))
.handler(a.handler.function(someservice))
.authorization(publicAndAuthenticatedAccess)
});
  1. Use the combine method: Amplify provides an a.combine() method that allows you to merge multiple schemas. This lets you define schemas in separate files and combine them:
// In schema1.ts
export const schema1 = a.schema({
model1: a.model({/*...*/}).authorization((allow) => [allow.publicApiKey()])
});

// In schema2.ts
export const schema2 = a.schema({
model2: a.model({/*...*/}).authorization((allow) => [allow.authenticated()])
});

// In your main schema file
import { schema1 } from './schema1';
import { schema2 } from './schema2';

const combinedSchema = a.combine([schema1, schema2]);
export const data = defineData({ schema: combinedSchema });

Remember that Amplify will use the most specific authorization rule available, and if multiple rules are present, they will be logically OR'ed. This means you can define global authorization rules and then override them with more specific rules at the model or field level as needed.
Sources
Building RAG-based applications with AWS Amplify AI Kit and Neon Postgres | Front-End Web & Mobile
Customize your auth rules - AWS Amplify Gen 2 Documentation

answered 11 hours ago