Difference between revisions of "Modules"
(Created page with "Modules in SocialStack are the main way to create small, portable, easy to test units of code. The best way to create a new one is via the generate command, but y...") |
|||
| Line 39: | Line 39: | ||
} | } | ||
</syntaxhighlight> | </syntaxhighlight> | ||
= Publishing a module = | |||
Modules can be shared to the world via [https://github.com/socialstack-core/modules the github repository]. You'll need to [https://cloud.socialstack.dev/en-admin/module/ create a new module entry on socialstack cloud first] which should be the desired installable name and the path within the "Core" repository. Adding a new entry is currently non-public because of this socialstack cloud dependency but will be fully public in the future. You can however edit the socialstack command line tools to point at something other than socialstack cloud to have a completely custom repository/ a superset of installable modules. | |||
Note that it's important to add the module entry first - that's because the commit handler specifically checks if committed changes are within known module paths and if so, then generates the new installable zip. If you create the module entry afterwards, just make a commit to any of the files in your modules path and it will then update for you. | |||
= Installing a published module = | |||
The socialstack command line tools have an install command that let you install a module from [https://github.com/socialstack-core/modules the github repository]. Typically use the path to the module that you want, like so: | |||
<syntaxhighlight lang="bash"> | |||
socialstack install Api/Pages | |||
socialstack install UI/Alert | |||
socialstack install Defaults | |||
</syntaxhighlight> | |||
"Defaults" is the package which gets installed when a new project is generated. | |||
= Editing changes = | |||
When installing a module its files are copied into your project in a directory called ThirdParty. You can edit the files in there, but it's generally recommended to avoid doing so unless necessary. This is because when you want to upgrade your project, the changes will be something you may end up needing to merge. | |||
Typically when making changes to a module that originated from the public repository, it's best to make the changes generic such that they can be contributed (by simply committing them to the github repo, or make a pull request there). For example if you're editing a UI module it's best to expose a React prop instead of adding your new project specific value in the source. If you're editing an API module, e.g. add a feature flag as a [[Configuration|config option]]. | |||
Revision as of 11:46, 1 December 2022
Modules in SocialStack are the main way to create small, portable, easy to test units of code. The best way to create a new one is via the generate command, but you can also install public ones. Importantly a module should be self-contained as much as possible with the smallest dependency footprint.
Making C# code modular
As C# is a statically typed language, it is inherently more rigid than languages like Javascript on the frontend. However, partial classes are very useful for this end goal of making extensible units of code. For this reason, every class outputted by the generate command is partial.
Why are partial classes useful? Let's take the User type for example. Modules want to extend this one all the time - a 2 factor authentication plugin may want to store some data in the user objects, modules for adding names and addresses and so on. Because the installed User class is partial, you can add fields to it without editing the original file. By adding fields to the User type, any User reference you end up with - either via the API, admin panel, events etc - will then have that field on it. Because the database storage mechanism is also generic, it will get automatically stored too. Therefore, adding a field to the User type is as simple as adding a file like this:
namespace Api.Users;
public partial class User{
public string MyCustomField;
}
Secondly, we also have a very fast and flexible events system inside the API. When a user object is created, an event is triggered (specifically that is Events.User.BeforeCreate and AfterCreate), which then any module can subscribe to. Just like with the content type itself, common events are fully automatic but you can also create your own.
Event listeners should be added once at startup. This means you'll either put them in service constructors, or in special EventListener classes which are constructed as a singleton for you.
[EventListener]
public class MyEventListener {
public MyEventListener(){
Events.User.BeforeCreate.AddEventListener(async (Context context, User user) => {
if(user == null){
return null;
}
// can await something here if needed!
// Because we're in a beforeCreate, we can edit the object including populating custom fields or validating them.
// If we have a validation failure, throw a PublicException.
// throw new PublicException("Incorrect date of birth", "dob/invalid");
return user;
});
}
}
Publishing a module
Modules can be shared to the world via the github repository. You'll need to create a new module entry on socialstack cloud first which should be the desired installable name and the path within the "Core" repository. Adding a new entry is currently non-public because of this socialstack cloud dependency but will be fully public in the future. You can however edit the socialstack command line tools to point at something other than socialstack cloud to have a completely custom repository/ a superset of installable modules.
Note that it's important to add the module entry first - that's because the commit handler specifically checks if committed changes are within known module paths and if so, then generates the new installable zip. If you create the module entry afterwards, just make a commit to any of the files in your modules path and it will then update for you.
Installing a published module
The socialstack command line tools have an install command that let you install a module from the github repository. Typically use the path to the module that you want, like so:
socialstack install Api/Pages
socialstack install UI/Alert
socialstack install Defaults
"Defaults" is the package which gets installed when a new project is generated.
Editing changes
When installing a module its files are copied into your project in a directory called ThirdParty. You can edit the files in there, but it's generally recommended to avoid doing so unless necessary. This is because when you want to upgrade your project, the changes will be something you may end up needing to merge.
Typically when making changes to a module that originated from the public repository, it's best to make the changes generic such that they can be contributed (by simply committing them to the github repo, or make a pull request there). For example if you're editing a UI module it's best to expose a React prop instead of adding your new project specific value in the source. If you're editing an API module, e.g. add a feature flag as a config option.