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
237 stars 20 forks source link

Need help in parsing the environment variables and passing to post request #188

Closed abbazs closed 1 year ago

abbazs commented 1 year ago

I'm trying to the following test code working, but it is not.

@host=http://localhost:3000
@app=testapp
@revision=master
@profile=dev

###
# @name session
{{
    console.log('Test 1');
}}
GET {{host}}

{{
    const fs = require('fs');
    const path = require('path');
    const httpyac = require('httpyac');
    const envFilePath = path.resolve(__dirname, '../../envs/api.env');
    fs.readFileSync(envFilePath, 'utf8')
      .split('\n')
      .filter(line => !line.startsWith('#'))
      .forEach(line => {
        const [name, value] = line.split('=', 1);
        process.env[name] = value;
      });
}}
POST {{host}}/login
Content-Type: application/json
{
    "username": "{{process.env.USER_ID}}",
    "password": "{{process.env.USER_PASSWORD}}",
}

I'm getting error response from server:

{
  "statusCode": 400,
  "message": "Unexpected token } in JSON at position 76",
  "error": "Bad Request"
}

How can I get this working?

AnWeber commented 1 year ago

The message looks like an error message from the server (maybe Spring Boot). The question for me would be what the request looked like and which of the two requests was sent (GET or POST). I will start from the POST. If only this POST was executed, probably the process.env variables are not defined. The previous script code is not executed because it is assigned to the previous request. Try looking at the sent requeset body (Output Channel httpyac - Request in VSCode)

I feel your code is rather complex. To read in env variables you would simply have to put them as .env in the same folder (see dotenv support, example). If you still want to read the file, using variables would be easier instead of process.env.

abbazs commented 1 year ago

The development environment rules doesn't allow me to hold any file ending with .env in the project folder, hence I was trying to hack this. As I could not env working, similar to this how can I get assigning the envs to variables working?

This is what I tried and I could not get it working.

host=http://localhost:3000
@app=testapp
@revision=master
@profile=dev

###
# @name session
{{
    console.log('Test 1');
}}
GET {{host}}

{{
    const fs = require('fs');
    const path = require('path');
    const httpyac = require('httpyac');
    const envFilePath = path.resolve(__dirname, '../../envs/api.env');
    fs.readFileSync(envFilePath, 'utf8')
      .split('\n')
      .filter(line => !line.startsWith('#'))
      .forEach(line => {
        const [name, value] = line.split('=', 1);
        exports[name] = value;
      });
}}
POST {{host}}/login
Content-Type: application/json
{
    "username": "{{USER_ID}}",
    "password": "{{USER_PASSWORD}}",
}
AnWeber commented 1 year ago

@abbazs There is a HTTPYAC_ENV global variable to define other locations to search for .env files

The script block is executed in your example only in GET request. You need to add a separator before your script block.

host=http://localhost:3000
@app=testapp
@revision=master
@profile=dev

###
# @name session
{{
    console.log('Test 1');
}}
GET {{host}}
###
{{
    const fs = require('fs');
    const path = require('path');
    const httpyac = require('httpyac');
    const envFilePath = path.resolve(__dirname, '../../envs/api.env');
    fs.readFileSync(envFilePath, 'utf8')
      .split('\n')
      .filter(line => !line.startsWith('#'))
      .forEach(line => {
        const [name, value] = line.split('=', 1);
        exports[name] = value;
      });
}}
POST {{host}}/login
Content-Type: application/json
{
    "username": "{{USER_ID}}",
    "password": "{{USER_PASSWORD}}",
}
abbazs commented 1 year ago

Got it working!

host=http://localhost:3000
@app=testapp
@revision=master
@profile=dev
###
{{
  const fs = require('fs');
  const path = require('path');
  const envFilePath = path.resolve(__dirname, '../../envs/api.env');
  const regex = /^([^=]+)=(.*)$/;
  fs.readFileSync(envFilePath, 'utf8')
    .split('\n')
    .filter(line => line && !line.startsWith('#'))
    .forEach(line => {
        const [, name, value] = line.match(regex);
        if (name && value){
          exports[name]=value;
        }
      });
}}
###
# @name session
{{
    console.log('Test 1');
}}
GET {{host}}
###
POST {{host}}/login
Content-Type: application/json
{
    "username": "{{USER_ID}}",
    "password": "{{USER_PASSWORD}}",
}
AnWeber commented 1 year ago

You could remove first separator ###. Your script block is executed for every request in the file. :-)