Customize and extend Amplication’s code generation process using Before and After lifecycle functions in plugins.
Amplication plugins offer powerful lifecycle functions that allow you to customize and extend the code generation process precisely where you need it. Every event within Amplication’s plugin system exposes these lifecycle functions, giving you consistent control throughout the resource generation process.
Each event in Amplication’s plugin system follows a predictable structure, offering both before
and after
hooks:
before
: This function executes before Amplication emits the main event logic. Use it to modify event parameters and tailor the default behavior before it happens.after
: This function executes after Amplication’s core event logic. It provides access to the generated modules or files, allowing you to apply transformations, add custom logic, or restructure outputs.Each event defines its specific EventParams
interface (T extends EventParams
), providing you with type-safe access to the relevant data for that particular stage of the generation process.
Let’s examine the signatures of the before
and after
functions to understand how you can interact with Amplication’s code generation:
This is the signature of all events of the Blueprint Engine.
This is the signature of all events of the Blueprint Engine.
This is the signature of all events of the built-in Node.js engine based on Amplication Standards
This is the signature of all events of the built-in .NET engine based on Amplication Standards
Parameters:
The Design Context provides access to shared information and utilities across all events within a plugin execution. Use it to retrieve configuration, access the service schema, and more.
These are the parameters specific to the event being handled. The type T
is
defined by the specific event interface, giving you access to relevant data
points to influence the generation.
FileMap
is used in blueprint plugins to represent generated files. It
provides a way to access and modify the generated files before they are
written to disk.
FileMap
is used in blueprint plugins to represent generated files. It
provides a way to access and modify the generated files before they are
written to disk.
A ModuleMap
is a structure containing the generated code modules as
key-value pairs, where keys are module paths and values are the code
content. This is your entry point to modify the generated code in Node.js
plugins.
Similar to ModuleMap
, FileMap
is used in .NET plugins to represent
generated files. It provides a way to access and modify the generated
files before they are written to disk.
Return Values:
The before
function should return a Promise
that resolves to the
(potentially modified) eventParams
. Returning the modified eventParams
allows you to influence the subsequent default behavior of the event.
The after
function should return a Promise
resolving to the (potentially modified) ModuleMap
. Returning the modified ModuleMap
ensures your changes are incorporated into the final generated output.
The after
function should return a Promise
resolving to the (potentially modified) ModuleMap
. Returning the modified ModuleMap
ensures your changes are incorporated into the final generated output.
Similarly, the .NET after
function should return a Promise
resolving to the modified FileMap<F>
.
Both before
and after
lifecycle functions have access to a global context
object that provides essential data and utilities. This context is shared between events and contains crucial information about your application.
Here are the key properties available in the context object:
Name | Type | Description |
---|---|---|
resourceType | keyOf typeOf EnumResourceType | The type of resource: MessageBroker , ProjectConfiguration , Service |
resourceInfo | AppInfo | General application data including name, description, version, ID, URL, and settings |
entities | Entity[] | List of entities in the service |
roles | Roles | List of roles in the service |
pluginInstallations | PluginInstallations | List of installed plugins |
topics | Topic[] | List of topics connected to the service |
modules | ModuleMap | Map of generated modules (files) |
DTOs | DTOs | List of generated DTOs |
plugins | PluginMap | Map of event names with their before/after functions and event parameters |
logger | BuildLogger | Logger for creating user-facing build logs |
utils | ContextUtil | Utility functions including skipDefaultBehavior and importStaticModules |
clientDirectories | ClientDirectories | Paths for admin UI generation (base, src, auth, public, api directories) |
serverDirectories | ServerDirectories | Paths for server generation (base, src, auth, scripts, messageBroker directories) |
For detailed information about these types and their definitions, check out the code-gen-types.ts file in the Amplication GitHub repository.
The before
function provides a powerful capability to skip Amplication’s default behavior through the context object. This allows you to completely override the default functionality with your own implementation:
By default, skipDefaultBehavior
is set to false
. When set to true
, Amplication will skip its default implementation, and you must provide alternative logic either in the before
function or in the corresponding after
function.
Use skipDefaultBehavior
with caution. Skipping default behavior without
providing proper alternative functionality can lead to unexpected results,
especially if other generated files depend on the skipped output.
after
FunctionsA common use case for after
functions is to restructure the generated files. Imagine you need to enforce a specific folder structure for all your organization’s services. The after
function is the perfect place to achieve this.
For example, you might want to:
resolvers
directory.The after
function gives you the flexibility to manipulate the generated ModuleMap
or FileMap
and reorganize files as needed to meet your project’s architectural requirements.
The best way to understand the power of before
and after
functions is to see them in action.
We encourage you to dive into the code of Amplication’s official plugins. These plugins are built using the same plugin framework and provide numerous practical examples of how to implement before
and after
lifecycle functions for various customization tasks.
By exploring these examples, you can gain insights into:
Browse our complete collection of official plugins in the Amplication Plugins Repository for more examples and inspiration.
Implement authentication and identity management in .NET applications using Microsoft Identity.
Add Redis caching capabilities to your Node.js applications for improved performance.
Configure PostgreSQL database integration for .NET applications.
Generate Helm charts for Kubernetes deployment of your applications.
To ensure your plugins are robust and maintainable, keep these best practices in mind when working with before
and after
functions:
Targeted Modifications in `after` Functions
In after
functions, focus on making specific, targeted changes to the generated files. Avoid wholesale replacement of entire files unless absolutely necessary. Smaller, incremental modifications are easier to understand, maintain, and less likely to introduce unintended side effects.
Careful Template Adjustments in `before` Functions
When modifying templates within before
functions, exercise caution. Changes
to templates can have a broad impact on code generation. Ensure you thoroughly
test any template modifications to prevent unintended consequences or
breakages in the generated code.
Strategic Use of `skipDefaultBehavior`
The skipDefaultBehavior
option (available in some events) should be used
judiciously within before
functions. Only utilize it if you intend to
completely override Amplication’s default code generation for that
specific event. In most cases, you’ll want to extend or modify the default
behavior, not replace it entirely.
Customize and extend Amplication’s code generation process using Before and After lifecycle functions in plugins.
Amplication plugins offer powerful lifecycle functions that allow you to customize and extend the code generation process precisely where you need it. Every event within Amplication’s plugin system exposes these lifecycle functions, giving you consistent control throughout the resource generation process.
Each event in Amplication’s plugin system follows a predictable structure, offering both before
and after
hooks:
before
: This function executes before Amplication emits the main event logic. Use it to modify event parameters and tailor the default behavior before it happens.after
: This function executes after Amplication’s core event logic. It provides access to the generated modules or files, allowing you to apply transformations, add custom logic, or restructure outputs.Each event defines its specific EventParams
interface (T extends EventParams
), providing you with type-safe access to the relevant data for that particular stage of the generation process.
Let’s examine the signatures of the before
and after
functions to understand how you can interact with Amplication’s code generation:
This is the signature of all events of the Blueprint Engine.
This is the signature of all events of the Blueprint Engine.
This is the signature of all events of the built-in Node.js engine based on Amplication Standards
This is the signature of all events of the built-in .NET engine based on Amplication Standards
Parameters:
The Design Context provides access to shared information and utilities across all events within a plugin execution. Use it to retrieve configuration, access the service schema, and more.
These are the parameters specific to the event being handled. The type T
is
defined by the specific event interface, giving you access to relevant data
points to influence the generation.
FileMap
is used in blueprint plugins to represent generated files. It
provides a way to access and modify the generated files before they are
written to disk.
FileMap
is used in blueprint plugins to represent generated files. It
provides a way to access and modify the generated files before they are
written to disk.
A ModuleMap
is a structure containing the generated code modules as
key-value pairs, where keys are module paths and values are the code
content. This is your entry point to modify the generated code in Node.js
plugins.
Similar to ModuleMap
, FileMap
is used in .NET plugins to represent
generated files. It provides a way to access and modify the generated
files before they are written to disk.
Return Values:
The before
function should return a Promise
that resolves to the
(potentially modified) eventParams
. Returning the modified eventParams
allows you to influence the subsequent default behavior of the event.
The after
function should return a Promise
resolving to the (potentially modified) ModuleMap
. Returning the modified ModuleMap
ensures your changes are incorporated into the final generated output.
The after
function should return a Promise
resolving to the (potentially modified) ModuleMap
. Returning the modified ModuleMap
ensures your changes are incorporated into the final generated output.
Similarly, the .NET after
function should return a Promise
resolving to the modified FileMap<F>
.
Both before
and after
lifecycle functions have access to a global context
object that provides essential data and utilities. This context is shared between events and contains crucial information about your application.
Here are the key properties available in the context object:
Name | Type | Description |
---|---|---|
resourceType | keyOf typeOf EnumResourceType | The type of resource: MessageBroker , ProjectConfiguration , Service |
resourceInfo | AppInfo | General application data including name, description, version, ID, URL, and settings |
entities | Entity[] | List of entities in the service |
roles | Roles | List of roles in the service |
pluginInstallations | PluginInstallations | List of installed plugins |
topics | Topic[] | List of topics connected to the service |
modules | ModuleMap | Map of generated modules (files) |
DTOs | DTOs | List of generated DTOs |
plugins | PluginMap | Map of event names with their before/after functions and event parameters |
logger | BuildLogger | Logger for creating user-facing build logs |
utils | ContextUtil | Utility functions including skipDefaultBehavior and importStaticModules |
clientDirectories | ClientDirectories | Paths for admin UI generation (base, src, auth, public, api directories) |
serverDirectories | ServerDirectories | Paths for server generation (base, src, auth, scripts, messageBroker directories) |
For detailed information about these types and their definitions, check out the code-gen-types.ts file in the Amplication GitHub repository.
The before
function provides a powerful capability to skip Amplication’s default behavior through the context object. This allows you to completely override the default functionality with your own implementation:
By default, skipDefaultBehavior
is set to false
. When set to true
, Amplication will skip its default implementation, and you must provide alternative logic either in the before
function or in the corresponding after
function.
Use skipDefaultBehavior
with caution. Skipping default behavior without
providing proper alternative functionality can lead to unexpected results,
especially if other generated files depend on the skipped output.
after
FunctionsA common use case for after
functions is to restructure the generated files. Imagine you need to enforce a specific folder structure for all your organization’s services. The after
function is the perfect place to achieve this.
For example, you might want to:
resolvers
directory.The after
function gives you the flexibility to manipulate the generated ModuleMap
or FileMap
and reorganize files as needed to meet your project’s architectural requirements.
The best way to understand the power of before
and after
functions is to see them in action.
We encourage you to dive into the code of Amplication’s official plugins. These plugins are built using the same plugin framework and provide numerous practical examples of how to implement before
and after
lifecycle functions for various customization tasks.
By exploring these examples, you can gain insights into:
Browse our complete collection of official plugins in the Amplication Plugins Repository for more examples and inspiration.
Implement authentication and identity management in .NET applications using Microsoft Identity.
Add Redis caching capabilities to your Node.js applications for improved performance.
Configure PostgreSQL database integration for .NET applications.
Generate Helm charts for Kubernetes deployment of your applications.
To ensure your plugins are robust and maintainable, keep these best practices in mind when working with before
and after
functions:
Targeted Modifications in `after` Functions
In after
functions, focus on making specific, targeted changes to the generated files. Avoid wholesale replacement of entire files unless absolutely necessary. Smaller, incremental modifications are easier to understand, maintain, and less likely to introduce unintended side effects.
Careful Template Adjustments in `before` Functions
When modifying templates within before
functions, exercise caution. Changes
to templates can have a broad impact on code generation. Ensure you thoroughly
test any template modifications to prevent unintended consequences or
breakages in the generated code.
Strategic Use of `skipDefaultBehavior`
The skipDefaultBehavior
option (available in some events) should be used
judiciously within before
functions. Only utilize it if you intend to
completely override Amplication’s default code generation for that
specific event. In most cases, you’ll want to extend or modify the default
behavior, not replace it entirely.