Appearance
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.
http
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
http
# 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:
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
http
GET https://httpbin.org
/get
Query Strings
A request query may contain any unicode characters except line separators and the ‘#’ symbol.
http
GET https://httpbin.org/anything?q=httpyac
It is also possible to split the query strings to different subsequent lines.
http
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.
http
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.
http
{{+
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.
http
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.
http
# @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).
http
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
http
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 < ...
.
http
POST https://httpbin.org/anything
Content-Type: application/json
< ./requestBodyImport.json
If you want to replace variables in the file please import it with <@
http
@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.
http
@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.
http
@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
http
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.
http
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.
http
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.
http
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.
http
@assetsDir=./
POST https://countries.trevorblades.com/graphql
Content-Type: application/json
gql Continents < {{assetsDir}}graphql.gql
{
"code": "EU"
}
Request Separators
Multiple requests defined in a single file must be separated from each other with a request separator symbol. A separator may contain comments.
http
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.
http
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.
http
@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.
http
proto < ./hello.proto
GRPC grpcb.in:9000/hello.HelloService/sayHello
{
"greeting": "world"
}
TIP
Own ChannelCredentials can be set simply using header channelCredentials
.
http
proto < ./hello.proto
{{@request
const grpc = require('@grpc/grpc-js');
request.channelCredentials = grpc.ChannelCredentials.createSsl();
}}
GRPC grpcb.in:9001/hello.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
http
proto < ./hello.proto
keepCase: true
longs: String
enums: String
defaults: true
oneofs: true
includeDirs: [`${__dirname}/request`]
GRPC grpcb.in:9000/hello.HelloService/sayHello
{
"greeting": "world"
}
The import of the proto file can also be done globally
http
proto < ./hello.proto
###
GRPC grpcb.in:9000/hello.HelloService/sayHello
{
"greeting": "world"
}
GRPC grpcb.in:9000/hello.HelloService/sayHello
{
"greeting": "john"
}
TIP
You can use Variable Substitution in file import and in proto-loader options.
http
@assetsDir=./
proto < {{assetsDir}}hello.proto
keepCase: true
longs: String
enums: String
defaults: true
oneofs: true
includeDirs: [`${assetsDir}/request`]
GRPC grpcb.in:9000/hello.HelloService/sayHello
{
"greeting": "world"
}
::: warn IncludeDirs of @grpc/proto-loader currently supports only absolute paths. :::
Unary RPC
Unary RPC behaves identically to Http requests. The url need to be in the following format
GRPC {{server}}/{{service}}/{{method}}
http
proto < ./hello.proto
GRPC grpcb.in:9000/hello.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.
http
proto < ./hello.proto
GRPC grpcb.in:9000/hello.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
.
http
proto < ./hello.proto
# @noStreamingLog
GRPC grpcb.in:9000/hello.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.
http
proto < ./hello.proto
GRPC grpcb.in:9000/hello.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.
http
proto < ./hello.proto
GRPC grpcb.in:9000/hello.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
http
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.
http
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.
http
# @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.
http
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
.
http
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.
http
# @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)
http
# @keepStreaming
MQTT tcp://broker.hivemq.com
subscribe: httpyac
If a body is specified, it will be published immediately after connecting.
http
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
.
http
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.
http
# @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.
http
# @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.
http
# @keepStreaming
MQTT tcp://broker.hivemq.com
Topic: testtopic/1
###
# @name test
{{
mqttClient.publish('testtopic/1', 'hello johnny')
}}
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
http
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
.
http
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
.
http
# @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
http
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.
http
AMQP amqp://guest:guest@localhost
amqp_method: ack
amqp_channel_id: 1
amqp_tag: 2
http
AMQP amqp://guest:guest@localhost
amqp_method: nack
amqp_channel_id: 1
amqp_tag: 2
http
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
http
AMQP amqp://guest:guest@localhost
amqp_method: purge
amqp_queue: httpyac_queue
Declare exchange
Declare a queue or exchange
http
AMQP amqp://guest:guest@localhost
amqp_method: declare
amqp_exchange: httpyac_exchange
http
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
http
AMQP amqp://guest:guest@localhost
amqp_method: bind
amqp_exchange: httpyac_exchange
amqp_queue: httpyac_queue
amqp_routing_key: command.send
http
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
http
AMQP amqp://guest:guest@localhost
amqp_method: bind
amqp_exchange: httpyac_exchange
amqp_exchange_destination: httpyac_exchange2
amqp_routing_key: command.send
http
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
http
AMQP amqp://guest:guest@localhost
amqp_method: delete
amqp_exchange: httpyac_exchange
http
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 |