GithubHelp home page GithubHelp logo

Comments (4)

mogronalol avatar mogronalol commented on June 15, 2024

There's actually a few things to consider when designing this DSL.

Do we want to retain the separation between URL components? So for example, when building we could have something along these lines:

get("https://www.host.com/path?queryParam=foo").willReturn(...)

But this abstracts away the separation of url components as stored in the JSON:

{
    "scheme" : "http",
    "destination" : "www.host.com",
    "path" : "/path",
    "query" : "?queryParam=foo"
}

Maybe the abstraction makes sense, and internally we can decompose it? But if that's the case where do we draw the line? So for example, should we have query parameters separate:

get("https://www.host.com/path").queryParam("queryParam", "foo").willReturn(...)

Or do we include them:

get("https://www.host.com/path?queryParam=foo").willReturn(...)

Or we could support both options, in which case we could do:

get("https://www.host.com/path?queryParam=foo").queryParam("otherParam", "bar").willReturn(...)

Which could then lead to some concatenation between them?

I also think the DSL should follow what we perceive to be the most common use case, so @tommysitu's idea of starting with a method, followed by URL makes sense:

method(url)

Then you can optionally do:

method(url).withBody(body).withHeader(key, value)

The alternative is plain old builder like this:

builder().withMethod(method).withBody(body)

The former forces you into including certain fields in your simulation, such as method, but you could get around this by doing anyMethod(url) or something along those lines. The latter is more flexible but maybe more verbose.

There's also considering whether we want to put the destination at the root of the DSL. For example:

destination("www.host.com")
    .get(path("/firstPath?query=foo")).willReturn(...)
    .post(path("/secondPath").body(body)).willReturn(...)
destination("www.other-host.com")
    .get(path("/firstPath?query=foo")).willReturn(...)
    .post(path("/secondPath").body(body)).willReturn(...)

Vs

    .get("www.host.com/firstPath?query=foo").willReturn(...)
    .post("www.host.com/secondPath").body(body).willReturn(...)
    .get("www.other-host.com/firstPath?query=foo").willReturn(...)
    .post("www.other-host.com/secondPath").body(body)).willReturn(...)

I think in this case I prefer the second option, as although you keep having to repeat the base url, the parameter is the full url which seems more expressive than path. The second option also means that you'd also have to create a hierarchical simulation, even if you only wanted one request:

destination("www.host.com")
    .get(path("/firstPath?query=foo")).willReturn(...)

vs

    .get("www.host.com/firstPath?query=foo").willReturn(...)

Again I think the second is slightly cleaner.

from hoverfly-java.

mogronalol avatar mogronalol commented on June 15, 2024

@danielbryantuk @tommysitu @benjih

from hoverfly-java.

tommysitu avatar tommysitu commented on June 15, 2024

@mogronalol some good comments there. The design choice to have service("host.com") as a top element is to make it more microservices testing oriented, and be able to chain multiple services to build simulation data:

hoverflyRule.simulate(
     service("foo.com")
          .get(path("/firstPath?query=foo")).willReturn(...)
          .post(path("/secondPath").body(body)).willReturn(...)
     .anotherService("bar.com")
           .get(path("/firstPath?query=bar")).willReturn(...)
)

from hoverfly-java.

mogronalol avatar mogronalol commented on June 15, 2024

We've gone done this route:

The rule is fluent and hierarchical, allowing you to define multiple service endpoints as follows:

hoverflyRule.setSimulation(
    service("www.my-test.com")

        .post("/api/bookings").body("{\"flightId\": \"1\"}")
        .willReturn(created("http://localhost/api/bookings/1"))

        .get("/api/bookings/1")
        .willReturn(success("{\"bookingId\":\"1\"\}", "application/json"))

    .anotherService("www.other-anotherService.com")

        .put("/api/bookings/1").body("{\"flightId\": \"1\"\"}")
        .willReturn(success())

        .delete("/api/bookings/1")
        .willReturn(noContent())

The entrypoint for the DSL is HoverflyDSL.service. After calling this you can provide a method and path, followed by optional request components.
You can then use willReturn to state which response you want when there is a match, which takes responseBuilder object that you can instantiate directly,
or via the helper class responseCreators.

from hoverfly-java.

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.