# The generic data model to define applications and abstractions
So instead of creating a in-house CRD, we decide to work out a generic design which can be applied to all use cases at least in Alibaba.
The first idea is, we should provide several building blocks to be able to define higher level abstractions per request by developers and operators. but without coupling with specific workload types or platforms. This is how this model differentiates from platform level solutions like Serverless/FaaS/PaaS. Bringing your own workloads and platform is the key.
The second idea is "separate concerns" instead of "a mixed bag". We premises that app developers, app operators (or automated operation platforms) and infrastructure engineers tend to focus on their own piece of data . Note that we will try to avoid any form of information isolation at the meantime.
In general, the model is composed by two parts:
1. Application: a group of runnable components.
2. ApplicationConfiguration: a object to claim and apply operational capabilities to every component.
### Application
This part which is the main concern for *developers*.

*Component* is the piece of data to define "what to run".
It's basically a wrapper of specific workload which is defined by given Custom Resource Definition (CRD). For example, you can define your own `WebServer` Custom Resource as a component like below:
```yaml
apiVersion: core.oam.dev/v1alpha2
kind: Component
metadata:
name: frontend
spec:
workload:
apiVersion: myapp.dev/v1
kind: WebServer
spec:
containers:
- name: my-nginx
image: nginx:1.16.1
resources:
limits:
memory: "200Mi"
ports:
- containerPort: 4848
protocol: "TCP"
env:
- name: WORDPRESS_DB_PASSWORD
value: ""
```
Or, a `Function` component:
```yaml
apiVersion: core.oam.dev/v1alpha2
kind: Component
metadata:
name: function-frontend
spec:
workload:
# this is a real FaaS workload in Alibaba
apiVersion: faas.alibaba.com/v1
kind: Function
spec:
runtime: java8
timeoutMilliseconds: 3000
blobCodeUrl: http://xxx/f36286e6-f070-498f-a520-6dd3a589bd90
env:
- name: debug
value: "true"
resources:
cpu:
required: 1
memory:
required: 2048M
triggers:
- type: http
- type: metaq
```
It could also be cloud resource of course, for example, a MySQL database defined by Crossplane which can be provided by AWS or AlibabaCloud:
```yaml
apiVersion: core.oam.dev/v1alpha2
kind: Component
metadata:
name: cloud-postgres-db
spec:
workload:
apiVersion: database.crossplane.io/v1alpha1
kind: PostgreSQLInstance
metadata:
name: app-postgresql
spec:
classSelector:
matchLabels: {}
writeConnectionSecretToRef:
name: postgresqlconn
engineVersion: "9.6"
```
The modern application is usually composed by multiple components, e.g. a Wordpress (PHP code + MySQL), or a machine learning training app (Parameter Server + Worker) etc.
### ApplicationConfiguration
This part is concern for *operators* or *automatic system* (e.g. PaaS/Serverless etc).

For components belonging to same application, ApplicationConfiguration object will reference them together.
For every component in the same configuration, operators (or the system) can apply various operational capabilities to it, for example, manual/auto scaling policy, routing policy, rollout strategy etc.
All these capabilities are named as *Traits* for component. This concept is borrowed from [trait system](https://doc.rust-lang.org/1.8.0/book/traits.html) from Rust language, i.e. the operational characteristics for the app.
```yaml
apiVersion: core.oam.dev/v1alpha2
kind: ApplicationConfiguration
metadata:
name: frontend-db-config
spec:
components:
- componentName: cloud-postgres-db
- componentName: frontend
traits:
- trait:
apiVersion: core.oam.dev/v1alpha2
kind: ManualScalerTrait
metadata:
name: frontend-scaler
spec:
replicaCount: 2
```
There's a special kind of trait named *Scope*. Unlike trait which must be per component, scope is designed to be shared by different components within the same application.
// TBD: continue to explain the model.