# Project structure and naming conventions

The blueprint layout, directory prefixes and service naming that keep a project predictable.

A well-structured project is one where anyone can predict the location of a piece of code before opening a single file. This page describes the conventions that Zato projects follow - the directory layout, what belongs where, and how services are named.

## The layout {#the-layout}

The starting point is the [project blueprint](https://github.com/zatosource/zato-project-blueprint), the same structure the [deployment tutorial](https://zato.io/tutorials/devops/deployment.html) works with:

```text
myproject
├── config
│   ├── enmasse
│   │   └── enmasse.yaml         # Channels, connections, security - the environment as YAML
│   ├── python-reqs
│   │   └── requirements.txt     # Extra Python packages your services need
│   └── user-conf
│       └── myproject.ini        # Your own configuration values
├── impl
│   ├── scripts
│   │   ├── run-container.sh     # Starts the environment
│   │   └── run-tests.sh         # Runs the tests
│   └── src
│       ├── api
│       │   └── crm.py
│       ├── common
│       │   └── models.py
│       └── util
│           └── formatting.py
└── testing
    └── tests
        ├── test_billing.py
        └── test_crm.py
```

Configuration and code are kept apart - `config` holds everything declarative, `impl/src` holds everything programmable, and `testing` holds the [tests](https://zato.io/docs/api-testing/). The whole tree is kept in git and is the single source of truth for the environment, per the GitOps model that [deployment](https://zato.io/tutorials/devops/deployment.html) describes.

## What belongs in each directory {#what-belongs-in-each-directory}

Directories under `src` start with one of eight prefixes, and the prefix states the role of the code inside:

| Prefix | What lives there |
| --- | --- |
| `api` | Services that external callers invoke - the entry points of your integrations |
| `services` | Same role as `api` - use whichever name reads better in your project |
| `channel` | Services bound to specific channel types, e.g. MLLP or WebSocket handlers |
| `adapter` | Services that talk to one external system each, wrapping its API details |
| `core` | Business logic that is independent of any transport or external system |
| `model` | [Data models](https://zato.io/docs/dev/model/) - the dataclasses that define inputs and outputs |
| `common` | Code shared by everything else - constants, base classes, shared models |
| `util` | Helper functions with no business meaning - formatting, parsing, conversions |

The prefixes are not just documentation - [hot deployment](https://zato.io/docs/dev/hot-deploy.html) deploys them in dependency order, shared code first, so `common`, `util` and `model` are always in place before the `api` services that import them. A directory only needs to start with the prefix, so `api_billing` and `api_hr` both count as `api`.

## The channel, adapter and core layers {#the-channel-adapter-and-core-layers}

The three middle prefixes express one pattern - an integration is a chain of three responsibilities, each in its own layer:

- A **channel** service receives the request and handles the transport - HTTP headers, HL7 wrapping, file encodings - and contains no business rules
- A **core** service implements the business rules and contains no transport logic and no code specific to external systems
- An **adapter** service calls one external system and encapsulates its API's details - its endpoints, its error codes, its pagination - independently of the reason it is being called

The payoff is that each layer changes independently - a new transport is a new channel service in front of the same core, and swapping a CRM vendor replaces one adapter without touching the business logic. The [REST adapter](https://zato.io/docs/dev/rest/rest-adapter.html) pattern is the ready-made building block for the adapter layer.

For a small project, the layers can be a single `api` directory with three modules. The separation of concerns applies regardless of the number of directories.

## Naming services {#naming-services}

Service names are dotted, lowercase, with words separated by dashes:

```python
# -*- coding: utf-8 -*-

from zato.server.service import Service

class GetCustomerDetails(Service):
    name = 'crm.customer.get-details'

    def handle(self):
        ...
```

The convention is `<project or system>.<entity>.<action>`:

- `crm.customer.get-details`
- `billing.invoice.create`
- `hr.employee.sync-all`

Service names are visible throughout an environment - they appear in logs, in the Dashboard, in [REST channels](https://zato.io/docs/dev/rest/channels.html) and in `self.invoke` calls, so a consistent scheme makes an environment self-describing. Group by system or business area first, never by transport - `crm.customer.get-details` stays correct when the same service gains a second channel.

Class names are derived from the last part of the service name - `GetCustomerDetails` for `get-details` - and one module holds the services of one entity or one narrow area, so every `crm.customer.*` service is defined in `api/customer.py`.

## Naming everything else {#naming-everything-else}

The same spirit extends to the objects defined in enmasse and the Dashboard:

- REST channels are named after what they expose, e.g. `api.customer` with the URL path `/api/customer/{customer_id}`
- Outgoing connections are named after the system they reach, e.g. `CRM` or `Billing API`, because that is the name your code uses - `self.rest['Billing API']`
- Security definitions are named after who uses them, e.g. `api.customer.basic-auth` or `Partner X API Key`

## Learn more {#learn-more}

- [Development documentation](https://zato.io/docs/dev/) - The complete reference for writing services
- [Requests and responses](https://zato.io/docs/dev/request-response/) - What a service receives, what it returns and how both are structured
- [Integration examples](https://zato.io/docs/dev/examples/) - Ready-made code for the systems you are likely to connect to
- [IDE and debugging](https://zato.io/docs/dev/ide/) - Write services in the Dashboard or in your own editor
- [Data models](https://zato.io/docs/dev/model/) - Declare inputs and outputs and have them validated for you
- [In-depth API tutorial](https://zato.io/tutorials/main/01.html) - The full platform tutorial, from installation to production patterns
