dot-http icon indicating copy to clipboard operation
dot-http copied to clipboard

add directives ie `@noredirect`

Open bayne opened this issue 6 years ago • 4 comments

bayne avatar Jan 13 '20 18:01 bayne

Along these same lines, I've been thinking about a feature like https://learning.postman.com/docs/postman/sending-api-requests/requests/#binary-data or for sending a GraphQL request (currently formatting the GraphQL request is a little messy).

I wanted to suggest some of the ideas for syntax I've been playing around with: Something between the headers and the body

...
authorization: {{access_token}}

{% body: file(image.png) %}
...

or

...
authorization: {{access_token}}

{% body: graphql %}
query {
   request {
       name
   }
}
...

The problem with this is it gets harder to define where the body starts and it also might not sync up as smoothly with @noredirect?

OR

What if we leveraged custom headers for dot-http:

...
authorization: {{access_token}}
dot-noredirect: true
dot-body: file(image.png)
...

dylanowen avatar Feb 14 '20 19:02 dylanowen

For context, the @noredirect was essentially to match what's available on IntelliJ's HTTP editor: https://www.jetbrains.com/help/idea/exploring-http-syntax.html#enable-disable-redirects

I think if dot-http was to support binary files I would imagine it to have a similar syntax:

< ./input_file.bin

... What if we leveraged custom headers for dot-http: ...

Not really liking the custom headers, the intent of this project is to try to minimize the difference between what the developer imagines is being sent on the wire compared to what is expressed in the script.

... for sending a GraphQL request (currently formatting the GraphQL request is a little messy).

Can you give some examples of this? I haven't been making GraphQL requests with dot-http so some more context would be helpful.

bayne avatar Feb 14 '20 22:02 bayne

Thanks for the context, it helps / I didn't know about IntelliJ's version. GraphQL requests are usually encapsulated in json, so a request body like:

{
  leftComparison: hero(episode: EMPIRE) {
    ...comparisonFields
  }
  rightComparison: hero(episode: JEDI) {
    ...comparisonFields
  }
}

fragment comparisonFields on Character {
  name
  appearsIn
  friends {
    name
  }
}

would be

POST {{base_url}}/graphql/

{
   "query": "{   leftComparison: hero(episode: EMPIRE) {     ...comparisonFields   }   rightComparison: hero(episode: JEDI) {     ...comparisonFields   } }  fragment comparisonFields on Character {   name   appearsIn   friends {     name   } }"
   "variables": {}
}

which is hard to edit/read after removing the newlines.

The real problem is that json doesn't support multiline strings. The API tests clients that I'm familiar with abstract out the json part and let you just write GraphQL queries.

How I've been handling it is:

GET {{base_url}}/ping

> {%
   client.global.set('QUERY', '{\
    leftComparison: hero(episode: EMPIRE) {\
      ...comparisonFields\
    }\
    rightComparison: hero(episode: JEDI) {\
      ...comparisonFields\
    }\
  }\
  fragment comparisonFields on Character {\
    name\
    appearsIn\
    friends {\
      name\
    }\
  }');
%}

###

POST {{base_url}}/graphql

{
   "query": "{{QUERY}}"
}

which I guess could be helped with a pre-request script

dylanowen avatar Feb 14 '20 22:02 dylanowen

First off, just wanted to say: very cool! My original use-case for dot-http was limited so I just kept the bare features that I needed. Your use-case let's us grow it be useful to a wider audience.

The directives should focus on changing the request in ways that are unrelated to it's contents. This is illustrated in that help doc I linked:

  • @no-redirect says to not follow redirects and just provide the actual response. No changes to the body or the headers, just behavior.
  • @no-log changes how the output is displayed to the user, once again does not modify the request

That was my intention for directives in general and would be following that for the future.

which I guess could be helped with a pre-request script

I think you are on to something here and I could see this being done in a way that is consistent with other parts of dot-http:

POST {{base_url}}/graphql

< {%
  var query = '{\
    leftComparison: hero(episode: EMPIRE) {\
      ...comparisonFields\
    }\
    rightComparison: hero(episode: JEDI) {\
      ...comparisonFields\
    }\
    }\
    fragment comparisonFields on Character {\
      name\
      appearsIn\
      friends {\
        name\
      }\
  }';

  return {
    "query": query
  };
%}

> {% console.log(response); %}

Note the symmetry of the syntax:

  • < {% ... %} for a request body generator
  • > {% ... %} for a response handler (existing)

Since I don't see solving this problem with a directive, let's move over to this issue: https://github.com/bayne/dot-http/issues/42

bayne avatar Feb 15 '20 19:02 bayne