Request
An HTTP request starts with a request line followed by optional header fields, message body, response handler, and previous response references.
Request-Line
A request line consists of a request method, target and the HTTP protocol version. If the request method is omitted, ‘GET’ will be used as a default. The HTTP protocol version can be also omitted.
GET https://www.google.de HTTP/1.1
GET https://www.google.de
###
https://www.google.de
TIP
The HTTP version is optional. But in this guide I have always added it because of syntax highlighting
If the Http version is specified, this can be used to control the use of HTTP2
# no version = http/1.1
GET https://www.google.de
GET https://www.google.de HTTP/1.1
GET https://www.google.de HTTP/2.0
Allowed Requests Methods are (only uppercase values are allowed):
GET | POST | PUT | DELETE | PATCH |
OPTIONS | CONNECT | TRACE | PROPFIND | PROPPATCH |
COPY | MOVE | LOCK | UNLOCK | CHECKOUT |
REPORT | MERGE | MKACTIVITY | MKWORKSPACE | VERSION-CONTROL |
A request path can be added in the next line
GET https://httpbin.org
/get
Query Strings
A request query may contain any unicode characters except line separators and the ‘#’ symbol.
GET https://httpbin.org/anything?q=httpyac
It is also possible to split the query strings to different subsequent lines.
GET https://httpbin.org/anything
?q=httpyac
&ie=UTF-8
Headers
Each header field consists of a case-insensitive field name followed by a colon (‘:’), optional leading whitespace, the field value, and optional trailing whitespace.
GET https://httpbin.org/anything
Content-Type: text/html
Authorization: Bearer token
If you use the same headers several times, it is possible to store them in a variable and reuse them.
{{+
const token = "test"
exports.defaultHeaders = {
'Content-Type': 'text/html',
'Authorization': `Bearer ${token}`
};
}}
###
GET https://httpbin.org/anything
...defaultHeaders
GET https://httpbin.org/anything
...defaultHeaders
Cookie
CookieJar support is enabled by default. All received Cookies, previously sent by the server with the Set-Cookie header are automatically sent back. It is possible to send own cookies to the server using cookie header.
GET https://httpbin.org/cookies
Cookie: bar=foo
WARNING
Cookies are only stored In-Memory and are cleared in VS Code with command httpyac.reset
It is possible to disable cookie support per request.
# @no-cookie-jar
GET https://www.google.de
Request Body
The request body can be represented as a simple message or a mixed type message (multipart-form-data).
POST https://httpbin.org/anything
Content-Type: application/x-www-form-urlencoded
grant_type=client_credentials
WARNING
The first content that is not recognized as a header or query string is interpreted as a request body. After that, no more header or query string can be specified.
Multiple Response Body could be separated using ===
. These request body are sent one after another. To wait for a message to be received before sending, you could use wait-for-server
MQTT tcp://broker.hivemq.com
topic: httpyac
Send one
===
Send two
=== wait-for-server
=== wait-for-server
Send three
Imported Request Body
A body can also be imported by using < ...
.
POST https://httpbin.org/anything
Content-Type: application/json
< ./requestBodyImport.json
If you want to replace variables in the file please import it with <@
@foo="bar"
POST https://httpbin.org/anything
Content-Type: application/json
<@ ./requestBodyImport.json
All files are read with UTF-8 encoding. If a different encoding is desired, provide it. All encodings supported by NodeJS are available.
@foo="bar"
POST https://httpbin.org/anything
Content-Type: application/json
<@latin1 ./requestBodyImport.json
WARNING
If the request body is configured in-place, whitespace around it will be trimmed. To send leading or trailing whitespace as part of the request body, send it from a separate file.
TIP
You can use Variable Substitution in file import.
@assetsDir=./
###
POST https://httpbin.org/anything
Content-Type: application/json
< {{assetsDir}}requestBodyImport.json
multipart/form-data
It is possible to mix inline text with file imports
POST https://httpbin.org/post
Content-Type: multipart/form-data; boundary=WebKitFormBoundary
--WebKitFormBoundary
Content-Disposition: form-data; name="text"
invoice_text
--WebKitFormBoundary
Content-Disposition: form-data; name="title"
invoice_title
--WebKitFormBoundary
Content-Disposition: form-data; name="invoice"; filename="invoice.pdf"
Content-Type: application/pdf
< ./dummy.pdf
--WebKitFormBoundary--
GraphQL
GraphQL queries are supported. Parsing Logic will automatically generate a GraphQL request body from the query and the optional variables.
POST https://countries.trevorblades.com/graphql
Content-Type: application/json
query Continents($code: String!) {
continents(filter: {code: {eq: $code}}) {
code
name
}
}
{
"code": "EU"
}
GraphQL fragments are also supported and are included in the body by name.
fragment ContinentParts on Continent {
code
name
}
POST https://countries.trevorblades.com/graphql
Content-Type: application/json
query Continents {
continents {
...ContinentParts
}
}
{
"code": "EU"
}
To import GraphQL File you need to use special GraphQL Import Directive.
POST https://countries.trevorblades.com/graphql
Content-Type: application/json
gql Continents < ./graphql.gql
{
"code": "EU"
}
TIP
You can use Variable Substitution in file import.
@assetsDir=./
POST https://countries.trevorblades.com/graphql
Content-Type: application/json
gql Continents < {{assetsDir}}graphql.gql
{
"code": "EU"
}
Request Separators / Global Regions
Multiple requests defined in a single file must be separated from each other with a request separator symbol. A separator may contain comments.
https://httpbin.org/post
### separator
https://httpbin.org/post
Alternatively, the request can also be specified in RFC 7230 Request line format, which also triggers a separation.
GET https://httpbin.org/post HTTP/1.1
GET https://httpbin.org/post HTTP/1.1
Using ###
Regions without a request can be defined. These global regions are executed and interpreted for all requests within the file. This way meta data, variables and scripts can be set for each request.
@host=https://httpbin.org
###
GET /post HTTP/1.1
GET /post HTTP/1.1
gRPC
It is also possible to send gRPC requests. The same request line format is used as for Http requests, but GRPC
must be specified as the request method.
proto < ./hello.proto
GRPC grpc.postman-echo.com/HelloService/sayHello
{
"greeting": "world"
}
TIP
Own ChannelCredentials can be set simply using header channelCredentials
.
proto < ./hello.proto
{{@request
const grpc = require('@grpc/grpc-js');
request.channelCredentials = grpc.ChannelCredentials.createSsl();
}}
GRPC grpc.postman-echo.com/HelloService/sayHello
{
"greeting": "world"
}
Protobuf Loader
To use the gRPC call, the proto file associated with the call must first be loaded. This is loaded using @grpc/proto-loader. This can be configured using options in the header format
proto < ./hello.proto
keepCase: true
longs: String
enums: String
defaults: true
oneofs: true
includeDirs: [`${__dirname}/request`]
GRPC grpc.postman-echo.com/HelloService/sayHello
{
"greeting": "world"
}
The import of the proto file can also be done globally
proto < ./hello.proto
###
GRPC grpc.postman-echo.com/HelloService/sayHello
{
"greeting": "world"
}
GRPC grpc.postman-echo.com/HelloService/sayHello
{
"greeting": "john"
}
TIP
You can use Variable Substitution in file import and in proto-loader options.
@assetsDir=./
proto < {{assetsDir}}hello.proto
keepCase: true
longs: String
enums: String
defaults: true
oneofs: true
includeDirs: [`${assetsDir}/request`]
GRPC grpc.postman-echo.com/HelloService/sayHello
{
"greeting": "world"
}
::: warn IncludeDirs of @grpc/proto-loader currently supports only absolute paths. :::
GRPC Reflection
Grpc Reflection support can be enabled using metaData # @grpc-reflection
# @grpc-reflection
GRPC grpc.postman-echo.com/HelloService/sayHello
{
"greeting": "world"
}
TIP
If you want to use it in global region, you need to provide server url in metaData (# @grpc-reflection <server>
)
Unary RPC
Unary RPC behaves identically to Http requests. The url need to be in the following format
GRPC {{server}}/{{service}}/{{method}}
proto < ./hello.proto
GRPC grpc.postman-echo.com/HelloService/sayHello
{
"greeting": "world"
}
Using header notation it is also possible to send meta data.
Header ChannelCredentials
or Authorization
are special and defines the authentication used by gRPC. If no such header is specified, grpc.credentials.createInsecure()
is used automatically
Server Streaming RPC
Server Streaming RPC is similar to a unary RPC, except that the server returns a stream of messages in response to a client’s request.
proto < ./hello.proto
GRPC grpc.postman-echo.com/HelloService/LotsOfReplies
{
"greeting": "world"
}
All responses are output as an intermediate result and summarized at the end as one overall response. If the intermediate results are not needed, they can be deactivated using # @noStreamingLog
.
proto < ./hello.proto
# @noStreamingLog
GRPC grpc.postman-echo.com/HelloService/LotsOfReplies
{
"greeting": "world"
}
Client Streaming RPC
Client Streaming RPC is similar to a unary RPC, except that the client sends a stream of messages to the server instead of a single message. To enable this, a custom script can be used that registers for the @streaming hook. This script must export a Promise at the end of which the client stream is terminated.
proto < ./hello.proto
GRPC grpc.postman-echo.com/HelloService/lotsOfGreetings
{
"greeting": "world."
}
{{@streaming
async function writeStream(){
await sleep(1000);
await $requestClient.send({
greeting: 'How are you?',
});
await sleep(1000);
await $requestClient.send({
greeting: 'I can stream.',
});
}
exports.waitPromise = writeStream();
}}
TIP
To control the wait time more easily, a method sleep
is provided that waits the number of milliseconds.
Bidirectional Streaming RPC
Bidirectional Streaming RPC is a combination of client streaming and server streaming.
proto < ./hello.proto
GRPC grpc.postman-echo.com/HelloService/BidiHello
{
"greeting": "world"
}
===
{
"greeting": "How are you?"
}
=== wait-for-server
=== wait-for-server
{
"greeting": "I can stream."
}
Server-Sent Events / EventSource
By using method SSE
an EventSource instance can be created. This opens a persistent connection to an HTTP server, which sends events in text/event-stream format. Adding the header event
the list of events to be output is specified
SSE https://postman-echo.com/server-events/5
Event: message
{{@streaming
async function writeStream(){
await sleep(10000);
}
exports.waitPromise = writeStream();
}}
The events of the server can be waited for by using streaming event. As soon as this hook has been successfully processed, the connection is terminated.
SSE https://postman-echo.com/server-events/5
Event: message
{{@streaming
async function writeStream(){
await sleep(10000);
}
exports.waitPromise = writeStream();
}}
TIP
Meta Data keepStreaming
can be used to respond to events until manually aborted.
# @keepStreaming
SSE https://postman-echo.com/server-events/5
Event: message
WebSocket
By using method WS
a WebSocket connection to a server can be opened. If a body is included in the request, it is sent immediately after the connection is established.
WS wss://socketsbay.com/wss/v2/1/demo/
{
"test": "httpyac"
}
{{@streaming
async function writeStream(){
await sleep(10000);
$requestClient.send({
"event": "ping",
"reqid": 45
});
await sleep(1000);
}
exports.waitPromise = writeStream();
}}
The events of the server can be waited for by using streaming event. As soon as this hook has been successfully processed, the connection is terminated. Within the streaming
block it is possible to send further message using websocketClient
.
WS wss://socketsbay.com/wss/v2/1/demo/
{
"test": "httpyac"
}
{{@streaming
async function writeStream(){
await sleep(10000);
$requestClient.send({
"event": "ping",
"reqid": 45
});
await sleep(1000);
}
exports.waitPromise = writeStream();
}}
TIP
Meta Data keepStreaming
can be used to respond to events until manually aborted. Every request with same url as the open Connection uses the same client.
# @keepStreaming
WS wss://socketsbay.com/wss/v2/1/demo/
TIP
All received messages are output as an intermediate result and summarized at the end as one overall response. If the intermediate results are not needed, they can be deactivated using # @noStreamingLog
.
TIP
If special options are needed for initialization, they can be configured in a NodeJS script using request.options
.
MQTT
By using method MQTT
a MQTT Client can be created. MQTT.js opens a TCP or WebSocket Connection to a MQTT Broker. The header Topic
specifies the topic to be registered (multiple specification allowed)
# @keepStreaming
MQTT tcp://broker.hivemq.com
subscribe: httpyac
If a body is specified, it will be published immediately after connecting.
MQTT tcp://broker.hivemq.com
Topic: httpyac
Hello, World
TIP
If the topic used for publishing is different from the topic used for replying, the headers subscribe
and publish
can be used instead.
The messages of the server can be waited for using streaming event. As soon as this hook has been successfully processed, the connection is terminated. Within the streaming
block it is possible to publish further message using mqttClient
.
MQTT tcp://broker.hivemq.com
publish: httpyac
{{@streaming
async function writeStream(){
await sleep(1000);
$requestClient.send("mqttPublish");
await sleep(1000);
}
exports.waitPromise = writeStream();
}}
TIP
Meta Data keepStreaming
can be used to respond to events until manually aborted.
# @keepStreaming
MQTT tcp://broker.hivemq.com
subscribe: httpyac
TIP
All received messages are output as an intermediate result and summarized at the end as one overall response. If the intermediate results are not needed, they can be deactivated using # @noStreamingLog
.
QoS, retain, username, password, keepAlive (10seconds default) and clean can be configured using header notation.
# @keepStreaming
MQTT tcp://broker.hivemq.com
Topic: testtopic/1
Qos: 1
username: foo
password: bar
TIP
If more options are needed for the initialization, they could be configured in a NodeJS script using request.options
.
As long as the connection of the MQTT instance to the MessageQueue exists, messages can also be published from other NodeJS blocks.
# @keepStreaming
# @name source
MQTT tcp://broker.hivemq.com
Topic: testtopic/1
###
# @name test
{{
$requestClient.send('hello test')
}}
AMQP/ RabbitMQ
By using method AMQP
a AMQP Client can be created. @cloudamqp/amqp-client opens a AMQP Connection to RabbitMQ Server. Following Methods can be used
Publish
Publish a new message to an exchange. Header amqp_exchange
defines the used exchange. amqp_routing_key
is optional and sets the used routing key
AMQP amqp://guest:guest@localhost
amqp_method: publish
amqp_exchange: httpyac_exchange
amqp_routing_key: command.send
{
"test": "{{$uuid}}"
}
A direct publish to a queue is available using amqp_queue
.
AMQP amqp://guest:guest@localhost
amqp_queue: httpyac_queue
{
"test": "test"
}
TIP
If no amqp_method header is present and a body is provided. publish is used as default
The following headers can also be defined
Header | Description |
---|---|
amqp_contentType | content type of body, eg. application/json |
amqp_contentEncoding | content encoding of body, eg. gzip |
amqp_delivery_mode | 1 for transient messages, 2 for persistent messages |
amqp_priority | between 0 and 255 |
amqp_correlation_id | for RPC requests |
amqp_replyTo | for RPC requests |
amqp_expiration | Message TTL, in milliseconds, as string |
amqp_message_id | messageId |
amqp_user_id | userId |
amqp_type | type |
TIP
All other headers that do not start with amqp_
are appended to the message as headers
Consume/ Subscribe
Consume messages from a queue. Messages will be delivered asynchronously. The messages of the server can be waited for by using streaming event. As soon as this hook has been successfully processed, the connection is terminated. Within the streaming
block it is possible to access additional methods of a AMQPChannel using amqpChannel
.
# @keepStreaming
AMQP amqp://guest:guest@localhost
amqp_method: consume
amqp_queue: httpyac_queue
TIP
Meta Data keepStreaming
can be used to consume message until manually aborted.
TIP
If no amqp_method header is present and no body is provided. consume is used as default
AMQP amqp://guest:guest@localhost
amqp_queue: httpyac_queue
{{@streaming
async function writeStream(){
await sleep(10000);
}
exports.waitPromise = writeStream();
}}
TIP
All received messages are output as an intermediate result and summarized at the end as one overall response. If the intermediate results are not needed, they can be deactivated using # @noStreamingLog
.
The following headers can also be defined
Header | Description |
---|---|
amqp_tag | tag of the consumer, will be server generated if left empty |
amqp_no_ack | f messages are removed from the server upon delivery, or have to be acknowledged |
amqp_exclusive | if this can be the only consumer of the queue, will return an Error if there are other consumers to the queue already |
Ack/ Nack/ Cancel
Consumed messages are not acked/ nacked automatically. If a message needs to get acked/ nacked automatically a manual ack/ nack needs to be called. You need to declare the same channelId (amqp_channel_id
) and deliveryTag (amqp_tag
) as the consumer.
AMQP amqp://guest:guest@localhost
amqp_method: ack
amqp_channel_id: 1
amqp_tag: 2
AMQP amqp://guest:guest@localhost
amqp_method: nack
amqp_channel_id: 1
amqp_tag: 2
AMQP amqp://guest:guest@localhost
amqp_method: cancel
amqp_channel_id: 1
amqp_tag: 2
The following headers can also be defined
Header | Description |
---|---|
amqp_requeue | if the message should be requeued or removed |
amqp_multiple | batch confirm all messages up to this delivery tag |
Purge
Purge all messages of a queue
AMQP amqp://guest:guest@localhost
amqp_method: purge
amqp_queue: httpyac_queue
Declare exchange
Declare a queue or exchange
AMQP amqp://guest:guest@localhost
amqp_method: declare
amqp_exchange: httpyac_exchange
AMQP amqp://guest:guest@localhost
amqp_method: declare
amqp_queue: httpyac_queue
Header | Description |
---|---|
amqp_passive | if the exchange name doesn't exists the channel will be closed with an error, fulfilled if the exchange name does exists |
amqp_durable | if the exchange should survive server restarts |
amqp_auto_delete | if the exchange should be deleted when the last binding from it is deleted |
amqp_exclusive | if the queue should be deleted when the channel is closed |
Bind/ Unbind queue to exchange
Bind and unbind queue of a exchange
AMQP amqp://guest:guest@localhost
amqp_method: bind
amqp_exchange: httpyac_exchange
amqp_queue: httpyac_queue
amqp_routing_key: command.send
AMQP amqp://guest:guest@localhost
amqp_method: unbind
amqp_exchange: httpyac_exchange
amqp_queue: httpyac_queue
amqp_routing_key: command.send
Bind/ Unbind exchange to exchange
Create or delete an Exchange to exchange binding
AMQP amqp://guest:guest@localhost
amqp_method: bind
amqp_exchange: httpyac_exchange
amqp_exchange_destination: httpyac_exchange2
amqp_routing_key: command.send
AMQP amqp://guest:guest@localhost
amqp_method: unbind
amqp_exchange: httpyac_exchange
amqp_queue: httpyac_queue
amqp_routing_key: command.send
Delete
Delete an exchange or queue
AMQP amqp://guest:guest@localhost
amqp_method: delete
amqp_exchange: httpyac_exchange
AMQP amqp://guest:guest@localhost
amqp_method: delete
amqp_queue: httpyac_queue
Header | Description |
---|---|
amqp_if_unused | only delete if the exchange doesn't have any bindings |
amqp_if_empty | only delete if the queue is empty |