# Contract Driven Development

APIs perform a number of behaviors; retrieve data, add data, delete data, etc.. What exactly a request and response looks like can be generally described, but as developers we need explicit details. While a human can recognize "firstName" and "fName" as the same things, a computer will not. By defining the behaviors of an API in a contract consumers (clients) and producers can build and test against the contracts and have confidence that their code will work when it is working with the real application.

In this section we will walk through the process of writing a new contract and updating an existing one. After completing this section, you can the walk through the process of validating the contracts and running the mock service as either a client-side developer or a server-side developer.&#x20;

## Fork and Clone Contracts Repo

The first steps is to fork the contracts repository located here: <https://github.com/wkorando/produce-contracts>

Once you have forked the repository clone it. From the root of `produce-contracts` navigate to `META-INF/com.ibm.developer/produce-service/0.0.1-SNAPSHOT/contracts` the contract we will be adding and updating will be in this folder.&#x20;

## Writing a Contract to Define Error Behavior

Contracts shouldn't just be covering the golden path. APIs will also be sent invalid requests as well. It's important that we also define how our API behaves in these scenarios so that clients can properly handle responses to invalid requests.&#x20;

Create a new file named: `findProduceByNameInvalidCharacter.yml`

In the file add the following:

```
name: find-produce-by-name-invalid-character
description: Find find all produce that matches supplied name
priority: 1
request:
  method: GET
  url: /api/v1/produce/+
  matchers:
    url:
      regex: "/api/v1/produce/^\\W+$"
response:
  status: 400
  body:
    errorMessage: "Produce name must be alpha numeric!"
  headers:
    Content-Type: application/json;charset=UTF-8

```

## Update Contract to Respond with Values in a Request

Contracts don't have to be entirely static. While it is important that the contracts behave in a predictable way, having some dynamic behavior can make them easier to test with or better able to simulate real world behavior. One way Spring Cloud Contract (SCC) to accomplish this is by sending in the response values from a request.&#x20;

SCC has a several [pre-built functions](https://cloud.spring.io/spring-cloud-contract/single/spring-cloud-contract.html#_referencing_the_request_from_the_response). To access this functionality you will use triple handle bars `{{{`to invoke these functions. Using jsonPath, fields within a request body can be referenced. If we wanted to reference the `name` field it would look like this:

```
name: "{{{ jsonpath this '$.name' }}}"
```

Let's update the `addProduce.yml` contract so the response is matches the request:

```
name: add-produce
description: Operation for adding a new produce item
request:
  method: POST
  url: /api/v1/produce
  headers:
    Content-Type: application/json;charset=UTF-8
  body:
    name: "Kiwi"
    subName: ""
    quantity: 75
  matchers:
    headers:
    - key: Content-Type
      regex: "application/json.*"
    body:
      - path: $.name
        type: by_regex
        predefined: only_alpha_unicode
      - path: $.subName
        type: by_regex
        predefined: only_alpha_unicode
      - path: $.quantity
        type: by_regex
        value: "[0-9]+"
response:
  status: 200
  body:
    id: 10
    name: "{{{ jsonpath this '$.name' }}}"
    subName: "{{{ jsonpath this '$.subName' }}}"
    quantity: "{{{ jsonpath this '$.quantity' }}}"
  headers:
    Content-Type: application/json;charset=UTF-8
  matchers:
    body:
      - path: $.id
        type: by_regex
        value: "[0-9]+"
```

## Commit and Push Changes

Once you have made all the changes be sure to commit and push those changes to your github repo.

```
git add .
git commit -m "adding contracts"
git push
```


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://angularkc-ccd.gitbook.io/workspace/contract-driven-development.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
