# Working with models

https://docs.serverpod.dev/1.2.0/concepts/models

Models are Yaml files used to define serializable classes in Serverpod. They are used to generate Dart code for the server and client, and, if a database table is defined, to generate database code for the server. Using regular `.yaml` files within `lib/src/models` is supported, but it is recommended to use `.spy.yaml` (.spy stands for "Serverpod YAML") to leverage syntax highlighting provided by the [Serverpod Extension](https://marketplace.visualstudio.com/items?itemName=serverpod.serverpod) for VS Code.

The files are analyzed by the Serverpod CLI when generating the project and creating migrations.

Run `serverpod generate` to generate dart classes from the model files.

## Class

```yaml
class: Company
fields:
  name: String
  foundedDate: DateTime?
  employees: List<Employee>
```

Supported types are [bool](https://api.dart.dev/dart-core/bool-class.html), [int](https://api.dart.dev/dart-core/int-class.html), [double](https://api.dart.dev/dart-core/double-class.html), [String](https://api.dart.dev/dart-core/String-class.html), [Duration](https://api.dart.dev/dart-core/Duration-class.html), [DateTime](https://api.dart.dev/dart-core/DateTime-class.html), [ByteData](https://api.dart.dev/dart-typed_data/ByteData-class.html), [UuidValue](https://pub.dev/documentation/uuid/latest/uuid_value/UuidValue-class.html), and other serializable [classes](#class), [exceptions](#exception) and [enums](#enum). You can also use [List](https://api.dart.dev/dart-core/List-class.html)s and [Map](https://api.dart.dev/dart-core/Map-class.html)s of the supported types, just make sure to specify the types. Null safety is supported. Once your classes are generated, you can use them as parameters or return types to endpoint methods.

### Limiting visibility of a generated class

By default, generated code for your serializable objects is available both on the server and the client. You may want to have the code on the server side only. E.g., if the serializable object is connected to a database table containing private information.

To make a serializable class generated only on the server side, set the serverOnly property to true.

```yaml
class: MyPrivateClass
serverOnly: true
fields:
  hiddenSecretKey: String
```

It is also possible to set a `scope` on a per-field basis. By default all fields are visible to both the server and the client. The available scopes are `all`, `serverOnly`, `none`.

```yaml
class: SelectivelyHiddenClass
fields:
  hiddenSecretKey: String, scope=serverOnly
  publicKey: String
```

:::info
Serverpod's models can easily be saved to or read from the database. You can read more about this in the [Database](https://docs.serverpod.dev/1.2.0/concepts/database/models.md) section.
:::

## Exception

The Serverpod models supports creating exceptions that can be thrown in endpoints by using the `exception` keyword. For more in-depth description on how to work with exceptions see [Error handling and exceptions](https://docs.serverpod.dev/1.2.0/concepts/exceptions.md).

```yaml
exception: MyException
fields:
  message: String
  errorType: MyEnum
```

## Enum

It is easy to add custom enums with serialization support by using the `enum` keyword.

```yaml
enum: Animal
values:
 - dog
 - cat
 - bird
```

By default the serialization will convert the enum to an int representing the index of the value. Changing the order may therefore have unforeseen consequences when reusing old data (such as from a database). Changing the serialization to be based on the name instead of index is easy.

```yaml
enum: Animal
serialized: byName
values:
 - dog
 - cat
 - bird
```

`serialized` has two valid values `byName` and `byIndex`. When using `byName` the string literal of the enum is used, when using `byIndex` the index value (0, 1, 2, etc) is used.

:::info

It's recommended to always set `serialized` to `byName` in any new Enum models, as this is less fragile and will be changed to the default setting in version 3 of Serverpod.

:::

## Adding documentation

Serverpod allows you to add documentation to your serializable objects in a similar way that you would add documentation to your Dart code. Use three hashes (###) to indicate that a comment should be considered documentation.

```yaml
### Information about a company.
class: Company
fields:
  ### The name of the company.
  name: String

  ### The date the company was founded, if known.
  foundedDate: DateTime?

  ### A list of people currently employed at the company.
  employees: List<Employee>
```

## Generated code

Serverpod generates some convenience methods on the Dart classes.

### copyWith

The `copyWith` method allows for efficient object copying with selective field updates and is available on all generated `class`es. Here's how it operates:

```dart
var john = User(name: 'John Doe', age: 25);
var jane = john.copyWith(name: 'Jane Doe');
```

The `copyWith` method generates a deep copy of an object, preserving all original fields unless explicitly modified. It can distinguish between a field set to `null` and a field left unspecified (undefined). When using `copyWith`, any field you don't update remains unchanged in the new object.

### toJson / fromJson

The `toJson` and `fromJson` methods are generated on all models to help with serialization. Serverpod manages all serialization for you out of the box and you will rarely have to use these methods by your self. See the [Serialization](https://docs.serverpod.dev/1.2.0/concepts/serialization.md) section for more info.

### Custom methods

Sometimes you will want to add custom methods to the generated classes. The easiest way to do this is with [Dart's extension feature](https://dart.dev/language/extension-methods).

```dart
extension MyExtension on MyClass {
  bool isCustomMethod() {
    return true;
  }
}
```

## Keywords

| **Keyword**                                                                                                      | Note                                                                                              | [class](#class) | [exception](#exception) | [enum](#enum) |
| ---------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------- | :-------------: | :---------------------: | :-----------: |
| [**values**](#enum)                                                                                              | A special key for enums with a list of all enum values.                                           |                 |                         |       ✅       |
| [**serialized**](#enum)                                                                                          | Sets the mode enums are serialized in                                                             |                 |                         |       ✅       |
| [**serverOnly**](#limiting-visibility-of-a-generated-class)                                                      | Boolean flag if code generator only should create the code for the server.                        |        ✅        |            ✅            |       ✅       |
| [**table**](https://docs.serverpod.dev/1.2.0/concepts/database/models.md)                                        | A name for the database table, enables generation of database code.                               |        ✅        |                         |               |
| [**managedMigration**](https://docs.serverpod.dev/1.2.0/concepts/database/migrations.md#opt-out-of-migrations)   | A boolean flag to opt out of the database migration system.                                       |        ✅        |                         |               |
| [**fields**](#class)                                                                                             | All fields in the generated class should be listed here.                                          |        ✅        |            ✅            |               |
| [**type (fields)**](#class)                                                                                      | Denotes the data type for a field.                                                                |        ✅        |            ✅            |               |
| [**scope**](#limiting-visibility-of-a-generated-class)                                                           | Denotes the scope for a field.                                                                    |        ✅        |                         |               |
| [**persist**](https://docs.serverpod.dev/1.2.0/concepts/database/models.md)                                      | A boolean flag if the data should be stored in the database or not can be negated with `!persist` |        ✅        |                         |               |
| [**relation**](https://docs.serverpod.dev/1.2.0/concepts/database/relations/one-to-one.md)                       | Sets a relation between model files, requires a table name to be set.                             |        ✅        |                         |               |
| [**name**](https://docs.serverpod.dev/1.2.0/concepts/database/relations/one-to-one.md#bidirectional-relations)   | Give a name to a relation to pair them.                                                           |        ✅        |                         |               |
| [**parent**](https://docs.serverpod.dev/1.2.0/concepts/database/relations/one-to-one.md#with-an-id-field)        | Sets the parent table on a relation.                                                              |        ✅        |                         |               |
| [**field**](https://docs.serverpod.dev/1.2.0/concepts/database/relations/one-to-one.md#custom-foreign-key-field) | A manual specified foreign key field.                                                             |        ✅        |                         |               |
| [**onUpdate**](https://docs.serverpod.dev/1.2.0/concepts/database/relations/referential-actions.md)              | Set the referential actions when updating data in the database.                                   |        ✅        |                         |               |
| [**onDelete**](https://docs.serverpod.dev/1.2.0/concepts/database/relations/referential-actions.md)              | Set the referential actions when deleting data in the database.                                   |        ✅        |                         |               |
| [**optional**](https://docs.serverpod.dev/1.2.0/concepts/database/relations/one-to-one.md#optional-relation)     | A boolean flag to make a relation optional.                                                       |        ✅        |                         |               |
| [**indexes**](https://docs.serverpod.dev/1.2.0/concepts/database/indexing.md)                                    | Create indexes on your fields / columns.                                                          |        ✅        |                         |               |
| [**fields (index)**](https://docs.serverpod.dev/1.2.0/concepts/database/indexing.md)                             | List the fields to create the indexes on.                                                         |        ✅        |                         |               |
| [**type (index)**](https://docs.serverpod.dev/1.2.0/concepts/database/indexing.md)                               | The type of index to create.                                                                      |        ✅        |                         |               |
| [**unique**](https://docs.serverpod.dev/1.2.0/concepts/database/indexing.md)                                     | Boolean flag to make the entries unique in the database.                                          |        ✅        |                         |               |
