Coder Social home page Coder Social logo

Comments (16)

quincy avatar quincy commented on May 30, 2024 3

I have a slightly different, but related, use case. https://stackoverflow.com/questions/50532051/pact-how-do-i-match-an-object-whose-keys-match-a-regular-expression

I have a domain object which we call a Schedule which is really nothing more than an ordered map. The keys are dates. You set an entry in the map to denote that the value for the Schedule is that new value on the given date, and all subsequent dates until the next highest valued key.

For example:

[
  {
      "accountId" : 1,
      "permissions" : [
         {
            "schedule" : {
               "01/01/2018" : false,
               "01/01/1900" : true
            },
            "permissionId" : 3
         }
      ]
   }
]

I would like to ensure that the proposed new functionality covers the case of mapping matched keys to primitive values as well as objects and arrays. I don't believe a change to the proposal is necessary for this, because as it is currently worded it doesn't preclude my use case.

Thanks!

from pact-specification.

uglyog avatar uglyog commented on May 30, 2024 1

After some thought, I've decided a matchValues matcher defined on the map would be better. See https://github.com/pact-foundation/pact-specification/blob/version-4/README.md#ignoring-the-keys-in-a-map

from pact-specification.

mefellows avatar mefellows commented on May 30, 2024 1

Just because a map is a ubiquitous concept doesn't mean it should be dumped into an API design.

APIs should be designed, not simply a reflection of internal data structures.

Nevertheless I'm happily convinced there are enough cases in the wild to support dynamic keys and this feature.

from pact-specification.

mefellows avatar mefellows commented on May 30, 2024

Thanks for posting this detailed request @Mende.

I actually asked a few people at my place of work when this came up on the forums, and unanimously this was seen as unusual to be exposed as an API. So I'm skeptical of it being a common case.

This will take some serious thought as it is pretty core to any matching logic, although you could see how it might be implemented from a users perspective.

from pact-specification.

uglyog avatar uglyog commented on May 30, 2024

Here is an example of a test that shows this behaviour in Pact-JVM: https://github.com/DiUS/pact-jvm/blob/master/pact-jvm-consumer-junit/src/test/java/au/com/dius/pact/consumer/WildcardKeysTest.java

from pact-specification.

mefellows avatar mefellows commented on May 30, 2024

I stand corrected

from pact-specification.

uglyog avatar uglyog commented on May 30, 2024

I propose we add a ignoreKeys flag to the matcher defined on the map. The current implementation in Pact-JVM is a work around and is causing other issues. I'll add this to the V4 spec.

from pact-specification.

joelgithub avatar joelgithub commented on May 30, 2024

Will this solve #401?

from pact-specification.

uglyog avatar uglyog commented on May 30, 2024

@joelgithub hopefully it will

from pact-specification.

andersthorbeck avatar andersthorbeck commented on May 30, 2024

I also have a use case similar to #47 (comment), where we are storing dates as keys.

The JSON we are trying to match looks something like this

{
  "id": {
    "type": "doc",
    "date": "2018-07-31",
    "seq": 123
  },
  "versions": {
    "2018-09-01": [
      {
        "status": "draft",
        "shortTitle": "My draft title"
      },
      {
        "status": "published",
        "shortTitle": "My published title"
      }
    ],
    "2018-08-02": [
      {
        "status": "published",
        "shortTitle": "My published title"
      }
    ]
  }
}

The versions JSON object has dynamic keys, where each key is a date. Ideally, we would like our pact to be able to verify both the structure of the values mapped to by these keys (array containing objects containing "status" and "shortTitle" keys, both of type string) and to be able to verify that each key matches an ISO8601 date format (ref. the date type).

I actually asked a few people at my place of work when this came up on the forums, and unanimously this was seen as unusual to be exposed as an API. So I'm skeptical of it being a common case.

This does not seem to me as a particularly outlandish use case. If we generalize this, what we really want is to be able embed a generic map (one of the most commonly used data structures) in the JSON response of one of our API endpoints, and to be able to use pact to verify the structure of both the values and the keys of that map.

from pact-specification.

quincy avatar quincy commented on May 30, 2024

@mefellows, thank you for your feedback. I agree that APIs should be designed. However, many of us are working on legacy projects which were created prior to Pact. We don't necessarily have the luxury of redesigning the API at this time but we'd still like to get contracts in place.

Let's say I was redesigning my API though. It is the job of this particular provider service to transmit domain objects to its consumers. These domain objects are schedules of values keyed by date. I can imagine transforming the data from something like the following:

[
  {
      "accountId" : 1,
      "permissions" : [
         {
            "schedule" : {
               "01/01/2018" : false,
               "01/01/1900" : true
            },
            "permissionId" : 3
         }
      ]
   }
]

to something like this instead:

[
  {
      "accountId" : 1,
      "permissions" : [
         {
            "schedule" : [
              { "01/01/2018" : false },
              { "01/01/1900" : true }
            ],
            "permissionId" : 3
         }
      ]
   }
]

That would make the API work with Pact as it is today. But I fail to see how this is fundamentally a better designed API. Perhaps you had something else in mind and I simply can't see it at the moment. Can you offer guidance on how something like this could be improved? Do you have some literature you could refer me to?

I am not trying to be argumentative, but I would like to understand your comment and make improvements in the work I do in the future.

from pact-specification.

mefellows avatar mefellows commented on May 30, 2024

Totally agree with you on the retrofitting use case, which is another strong reason to support this.

Whether I agree with it or not doesn't matter, the fact that it is common in the real world is a good enough reason to support it.

FWIW I would have each item within schedule mapped to something more like the following:

[
  {
      "accountId" : 1,
      "permissions" : [
         {
            "schedule" : [
                { 
                    "date": "01/01/2018",
                    "enabled": true 
                },
                { 
                    "date": "01/01/1900",
                    "enabled": false 
                },
            ],
            "permissionId" : 3
         }
      ]
   }
]

Having each schedule as a domain object keyed by well-defined names allows greater flexibility in the model should you choose to expand, and is more easily modelled by today's tooling (albeit OAS will be able to sort-of support this down the track: OAI/OpenAPI-Specification#1505)

from pact-specification.

quincy avatar quincy commented on May 30, 2024

Thanks for sharing your opinion @mefellows. I appreciate the insight.

from pact-specification.

tcanavan avatar tcanavan commented on May 30, 2024

Will this be implemented in 4.0.0?

from pact-specification.

uglyog avatar uglyog commented on May 30, 2024

Not necessarily. The new matcher is added behaviour, and doesn't change the structure of the pact file.

from pact-specification.

uglyog avatar uglyog commented on May 30, 2024

Released values matcher with Pact-JVM and Pact-Rust

from pact-specification.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.