AnWeber / vscode-httpyac

Quickly and easily send REST, Soap, GraphQL, GRPC, MQTT and WebSocket requests directly within Visual Studio Code
https://marketplace.visualstudio.com/items?itemName=anweber.vscode-httpyac
MIT License
224 stars 20 forks source link

Found one case when "Generate Code" command executes request, but does not display generated code #170

Open woolfas opened 1 year ago

woolfas commented 1 year ago

Steps to reproduce:

  1. In VSCode with the HttpYac extension installed create three http scripts: first.http:
    
    ### Apple
    # @name send_apple
    POST https://httpbin.org/anything
    Content-Type: application/json

{ "id": "0001", "type": "fruit", "name": "Apple" }

**second.http**:

Cake

@name send_cake

POST https://httpbin.org/anything Content-Type: application/json

{ "id": "0002", "type": "donut", "name": "Cake" }

**third.http**:

All

@name send_all

@import first.http

@import second.http

@forceRef send_apple

@forceRef send_cake


2. Now open the `third.http` and put the cursor to `@forceRef send_apple` line.
3. Execute `httpYac: Generate Code` command

Expected results: System finds `send_apple` region in `first.http`, reads the request data and generates code for that request.
Actual results: System executes `send_apple` and `send_cake` regions without generating any code.

Basically my expectation is that if cursor is placed on any @forceRef or @ref line and "Generate Code" command is being executed, then system should generate it for the region which is referenced. If cursor is placed on the request line, then system should generate the code for the selected request.
AnWeber commented 1 year ago

@woolfas I had to take my time for the feature. I didn't want to reject it because it was complex to implement. I would have a simple solution by now. In the case where the current scope does not contain a request (like in third.http), I think your logic makes sense. Currently, no code generation would be generated at all. In the case where a request is available I don`t find it ideal from a UX point of view. Using command via command palette using the selected line may make sense. However, it is also possible to trigger generation using CodeLens above the request. In this case, one would probably expect the request itself again. In my application I cannot distinguish the two cases and therefore I do not want to adjust the logic for these cases.

AnWeber commented 1 year ago

My proposed solution is released with v6.0.0. Please test my change. Thanks.

woolfas commented 1 year ago

Hi. I tested your changes and I would say - partially works.

Here's the issues I found:

  1. If in third.http I use

    # @ref send_apple
    # @ref send_cake

    the code is generated for both lines, but only once. If I try to execute httpYac: Generate Code command the second time, then nothing is displayed at all. I assume this might be due to @ref caching behavior. However, before the code is generated and displayed on the screen, system still executes all the endpoints in the selected region and only after all of them are executed, only then the code is generated and displayed on the screen (I noticed that because I have a responseLogging hook implemented which logs all the executions to files). I would expect that actual execution of endpoints should be skipped when generating the code.

  2. If in third.http I use

    # @forceRef send_apple
    # @forceRef send_cake

    command httpYac: Generate Code does not display any generated code at all, but instead it executes all the endpoints in the region. Though I would expect it should work the same way as using @ref.

AnWeber commented 1 year ago

The current implementation is that I execute all requests and search for the named variable at the end. An abort is difficult, since I must either reset the complete cache, or provide a general registration of a codeGenerationPlugin, which is then armed if necessary. To solve the caching problem with @ref, I also need to clear the cache. An alternative would be to use the @ref and thus also @import logic directly and only call the required request. However, it could then happen that this uses other variables as with real execution. So many options and none I like.