Bohdan Petrenko
Bohdan Petrenko

Reputation: 1155

Spring cloud contracts with generic api

How to use spring cloud contracts with generic api. I'm asking about REST contracts on producer service. So consider an example. I have a service which allows to store user data into different formats into database and acts like proxy between service and database. It has parameters required for all consumers, and parameters which depend on a consumer.

class Request<T> {
    Long requestId;
    String documentName;
    T documentContent;
}

And it has two consumers.

Consumer 1:

{
  "requestId": 1,
  "documentName": "login-events",
  "documentContent": {
    "userId": 2,
    "sessionId": 3
  }
}

Consumer 2:

{
  "requestId": 1,
  "documentName": "user-details",
  "documentContent": {
    "userId": 2,
    "name": "Levi Strauss",
    "age": 11
  }
}

As you can see documentContent depends on consumer. In I want to write such contracts, which will check content of this field on consumer side and ignore it on producer side. Options like

"documentContent": ["age": $(consumer(11))] //will produce .field(['age']").isEqualTo(11)

and

"documentContent": ["age": $(consumer(11), producer(optional(anInteger())))] //will require field presence

didn't work. Of course I may write "documentContent": [] or even ignore this field in contracts, but I want them to act like Rest Api documentation. Does anybody has ideas how to solve this?

Upvotes: 0

Views: 101

Answers (2)

Bohdan Petrenko
Bohdan Petrenko

Reputation: 1155

I found solution, that is more applicable for my case (groovy code):

def documentContent = [
  "userId": 2,
  "sessionId": 3
]
Contract.make {
  response {
    body(
      [
      ............
      "documentContent" : $(consumer(documentContent), producer(~/.+/)),
      ............
      ]
    )
  }
}

But please, take into consideration, that I stubbed documentContent value with a String ("documentContent") in producer contract test.

Upvotes: 0

Marcin Grzejszczak
Marcin Grzejszczak

Reputation: 11149

Ignore the optional element and define 2 contracts. One with the age value and one without it. The one with the age value should contain also contain a priority field. You can read about priority here https://cloud.spring.io/spring-cloud-static/spring-cloud-contract/2.2.0.RELEASE/reference/html/project-features.html#contract-dsl-http-top-level-elements

It would look more or less like this (contract in YAML):

priority: 5 # lower value of priority == higher priority
request:
  ...
  body:
     documentContent:
         age: 11
response:
  ...

and then the less concrete case (in YAML)

priority: 50 # higher value of priority == lower priority
request:
  ...
  body:
     documentContent:
         # no age
response:
  ...

Upvotes: 1

Related Questions