bidirekt publish takes any number of files and folders, and all the files of one publish are one contract. A folder stands for every .yaml and .yml file under it, subfolders included. The order does not matter, and the shell expands globs such as contracts/*.yaml. Reports name a file you passed by the path you typed, and a file found in a folder by the folder and its path inside it, such as contracts/rest/pets.yaml.
- One schema namespace. A schema declared in one file can be named from any other. The same name declared twice is a duplicate. A file that names schemas declared elsewhere is valid only when published together with that file.
- A provider declares each resource once. Files may split the endpoints, the methods or even the statuses of one method between them, but the same resource in two files is a duplicate. A file reached twice, such as a file passed on its own and again through its folder, is read once and is not a duplicate. A request has no status, so the
requestof an endpoint and method belongs in exactly one file, even when its responses are spread over several. - A consumer merges by union. Each module of a consumer may declare the resources it reads in its own file. Fragments of the same resource merge: in a response, a property is optional only if every fragment allows it, and nullable only if every fragment accepts
null; in a request, it is required only if every fragment sends it, and nullable if any fragment may sendnull. A property that one fragment leaves out together with its parent is not made optional: only the parent is. Two fragments that give one property different types are rejected.
A provider that keeps the 201 of POST /pets in one file and its 400 in another writes request in only one of them:
# pets.yaml provides: rest: /pets: post: request: NewPet responses: 201: Pet
# pets_errors.yaml provides: rest: /pets: post: responses: 400: Error
Writing request: NewPet in pets_errors.yaml too declares the request of POST /pets twice:
contract validation failed - pets_errors.yaml: duplicate resource "provides POST /pets request", also declared in pets.yaml
Two modules of the consumer petstore_web read the same GET /pets/*, each its own subset:
# web_list.yaml consumes: petstore_api: rest: /pets/*: get: responses: 200: PetRow schemas: PetRow: type: object properties: petId: type: integer name: type: string
# web_card.yaml consumes: petstore_api: rest: /pets/*: get: responses: 200: PetCard schemas: PetCard: type: object properties: petId: type: integer photoUrl: type: string optional: true
Published together, petstore_web reads petId and name as required and photoUrl as optional, so a provider that returns only petId and name is compatible. Remove optional: true from web_card.yaml and photoUrl becomes required, because one reader needs it.