Domain or domain model is what makes the project unique. With requirements and terminology of the problem being solved in mind (the problem context), we build an abstraction that consists of entities, their relationships and logic that operates these entities. In order to focus on the complex part of the problem, domain is, ideally, separated from infrastructure part of the system (i.e. how to save data into database, how to form HTTP response etc.).
Note: Such isolation is suitable for complex systems. If your project domain is basically create/read/update/delete for a set of records with not much complex logic it makes no sense to apply complex solution to a simple problem. Individual concepts of domain design below could be applied separately so make sure to check these even if your project isn't that complicated.
It is nearly impossible to build a model that solves multiple problems that is not too complicated by itself. Therefore, it is a good practice to divide domain into several use-cases and have a separate model for each use-case. Such separated models are called "bounded contexts".
There are various building blocks that are typically used when describing domain models. It is not mandatory to use all of them.
Entity is an uniquely identifiable object such as user, product, payment etc. When comparing them, you're checking ID, not the attribute values. If there are two objects with different attributes but the same ID, they are considered the being the same thing.
Value object describes an object by its characteristincs. For example, a price that consists of value and currency. When comparing such objects you're checking actual values. If they match, object is considered being the same.
Aggregate is a set of domain objects such as entities and value objects and additional data that could be treated as a single unit. It usually represents a compound object from domain model such as shop order or HR person dossier.
One of the components of an aggregate is called a root. The root identifies an aggregate as a whole and should be used to access it.
An aggregate, while processed, may raise events. For example, when order is confirmed,
OrderConfirmed event would
be risen so other parts of the system may react on these.
Service is a class that contains a standalone operation within the context of your domain model.
Repository task is to abstract away how domain objects are obtained. These are usually separated in two parts: an interface that stays in the domain layer and implementation that is situated in infrastructure layer. In such way domain doesn't care how data is obtained and saves and may be focused around the complicated business logic instead.