Appirator applications are made from a mix of resource class definitions, events and their associated handlers. Each class can have its own configuration, can have properties that are primitive or are complex, using other class definitions. Classes additionally have methods, event handlers, migrations, access rules, validation, modifiers and more.
Resource classes are very powerful in their own right and there is essentially no limit to what can be done with them and how complex applications and APIs can be built using them. Resource objects are instances of resource classes. These are normally stored somewhere, either within the internal store or within an external store. But they don’t have to be stored. The ability to store resource objects in multiple ways means that resource classes can come in several configurations. These can be seen below.
The simplest resource class is one that has no logic and no event handling. The resource uses simple CRUD rules and its resource objects are stored in the Appirator internal store. A resource class of this nature can be configured and published in a matter of minutes.

While it is recommended that resource classes be kept simple, Appirator allows you to make them as complex as you need them to be. Classes support event handling, access rules, validation and much more.
Every CRUD operation on a resource object causes an event to be generated for that object. These events are handled on the resource class or globally. Event handlers can be synchronous or asynchronous. Larger applications and APIs require event handlers to perform their background processing, to ensure that API response times are minimised and to provide a guarantee that asynchronous orchestration logic is performed correctly. Such background processing invariably creates other resource objects that are stored as needed, as well as non-persistent objects that are used as transient event objects.

By default, resource classes are stored in the Appirator internal store. They can be optionally stored in any other store that has been built for the resource class using the Store type.
Stores and proxies within Appirator are essentially the same thing. Stores need to handle CRUD operations for their resource classes and they can use practically any protocol under the hood, including a simple replay of the resource object against an external REST endpoint. By using an external REST API as a store, the store is effectively a REST proxy. Because stores are high customisable, developers can use more than one external endpoint in them and it is therefore possible to have a single resource object in Appirator that binds to multiple external endpoints for its data.
Custom stores also need to handle their own identifiers and these identifiers are the identifiers that are used in the inbound API URLs.

Applications can use a mix of resource class stores, including the default internal store, any number or combination of external custom stores, hybrid stores and no storage.
A hybrid store is a special class of store used in Appirator where parts of a resource object are stored in the internal store and parts are stored in one or more custom external stores. There are a number of reasons why such a scenario might be used, for example an enterprise may have an existing API that for business reasons can’t be extended so they create an extended model with Appirator that uses their existing API for its main data and Appirator’s internal store for the extended data.

There are several important caveats when using hybrid stores:
Resource objects don’t need to be stored at all. Sometimes they’re just used to initiate an event flow within the application. In order to make a resource object non-persisting, the resource class simply needs to be marked as such. When resource classes are non-persisting, only one operation is allowed on them - CREATE. Synchronous and asynchronous event handling is still possible on the object, however, because the object is not stored, every asynchronous event handler effectively receives its own copy of the event and every synchronous event handler uses a shared object.

Some examples of where non-persisting resource objects are used are: