{"id":17434616,"url":"https://github.com/pieropatron/amqp-client","last_synced_at":"2026-04-28T08:39:58.018Z","repository":{"id":172470002,"uuid":"649279374","full_name":"pieropatron/amqp-client","owner":"pieropatron","description":"amqp 0-9-1 streamable client","archived":false,"fork":false,"pushed_at":"2023-06-05T06:18:13.000Z","size":199,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-08-15T08:15:38.102Z","etag":null,"topics":["amqp-client","amqp0-9-1","nodejs","promise-api","stream-api","streams","tiny","typescript"],"latest_commit_sha":null,"homepage":"","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/pieropatron.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2023-06-04T11:09:59.000Z","updated_at":"2023-06-04T14:26:39.000Z","dependencies_parsed_at":null,"dependency_job_id":"63fb7dac-3268-43b7-9579-9e547b429d69","html_url":"https://github.com/pieropatron/amqp-client","commit_stats":null,"previous_names":["pieropatron/amqp-client"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/pieropatron/amqp-client","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pieropatron%2Famqp-client","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pieropatron%2Famqp-client/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pieropatron%2Famqp-client/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pieropatron%2Famqp-client/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/pieropatron","download_url":"https://codeload.github.com/pieropatron/amqp-client/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pieropatron%2Famqp-client/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":32373515,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-27T20:07:02.737Z","status":"online","status_checked_at":"2026-04-28T02:00:07.250Z","response_time":56,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["amqp-client","amqp0-9-1","nodejs","promise-api","stream-api","streams","tiny","typescript"],"created_at":"2024-10-17T09:07:46.439Z","updated_at":"2026-04-28T08:39:54.106Z","avatar_url":"https://github.com/pieropatron.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# amqp-client\n\ntiny amqp 0-9-1 streamable client\n\n[![NPM version](https://img.shields.io/npm/v/@pieropatron/amqp-client.svg?style=flat-square)](https://www.npmjs.com/package/@pieropatron/amqp-client)\n[![NPM downloads](https://img.shields.io/npm/dm/@pieropatron/amqp-client.svg?style=flat-square)](https://www.npmjs.com/package/@pieropatron/amqp-client)\n\nIdea of this project is to provide easy of use client for work with rabbit-mq, which should allow to post and read message bodies as streams.\n\n# Introduction\nStarting to work with Rabbit MQ it is often a bit complex to understand its philosophy: how to correctly make connection, then using of channels, publish and consume messages and so on. Even if we need to do only something simple, like just read messages from one Queue of some 3rd party app, we'll had to study a lot of things about Rabbit MQ, AMQP and so on. This client (in theoury) should to allow of easy start to work with Rabbit MQ.\nAnother problem is that inspite of ability of Rabbit-MQ to transmit big-size messages (splitting them to chunks of liimited size), I didn't found in popular libraries for nodejs to process this correct. As I understand, they trying to cache all chunks in memory while message will not completely received, which is really not safe for nodejs and it's memory restrictions. Thats why I also added to this client ability to use message bodies as streams. In result, it should allow to save infromation, for example, to files directly after receive message chunks.\n\nNB: This client is not well-tested yet, so, please, be careful using it!\n\n# Install\n\n`npm install @pieropatron/amqp-client`\n\nOR\n\n`npm install https://github.com/pieropatron/amqp-client`\n\n# API\n\n## Create client\n\n``` ts\nimport {Client} from '@pieropatron/amqp-client';\n\n// create client with default values of options\nconst client = new Client({\n\thost: '127.0.0.1',\n\tport: 5672,\n\tusername: 'guest',\n\tpassword: 'guest',\n\tauth_mechanism: ['AMQPLAIN', 'PLAIN'],\n\tprotocol: 'amqp:',\n\tchannel_max: 0,\n\tframe_max: 0,\n\theartbeat: 0,\n\tlocale: 'en_US',\n\tvhost: '/',\n\tconnection_timeout: 60000\n});\n```\n\n## Work with exchanges\n\n``` ts\n// get helper to work with exchanges\nconst exchange = client.exchange(\"test\");\n\n// Create exchange if not exists\nawait exchange.declare({\n\tstorage_type: 'durable',\n\ttype: 'direct',\n\talternate_exchange: '',\n\tinternal: false\n});\n\n// Check if exchange exists\nconst exists: boolean = await exchange.exists();\n\n// Bind exchange to \"destination\" exchange with \"routing key\".\nconst bound: boolean = await exchange.bind({\n\tdestination: \"\",\n\trouting_key: \"\"\n});\n\n// Unbind exchange from \"destination\" exchange with \"routing key\".\nconst unbound: boolean = await exchange.unbind({\n\tdestination: \"\",\n\trouting_key: \"\"\n});\n\n// Delete exchange\nconst deleted = await exchange.delete();\n```\n\n## Work with queues\n\n``` ts\n// get helper to work with queues\nconst queue = client.queue(\"test\");\n\n// Create queue if not exists\nawait queue.declare({\n\tstorage_type: 'durable',\n\tqueue_type: 'classic',\n\tprivate: false\n});\n\n// Check if queue exists\nconst exists: boolean = await queue.exists();\n\n// Get current queue stat\nconst stat: {queue: string, message_count: number, consumer_count: number} = await queue.stat();\n\n// Bind queue to exchange with \"routing key\".\nconst bound: boolean = await queue.bind({\n\texchange: \"\",\n\trouting_key: \"\"\n});\n\n// Unbind queue from exchange with \"routing key\".\nconst unbound: boolean = await queue.unbind({\n\texchange: \"\",\n\trouting_key: \"\"\n});\n\n// remove all messages from queue\nconst purged: {message_count: number} = await queue.purge();\n\n// Delete queue\nconst deleted: {message_count: number} = await queue.delete();\n```\n\n## Publish messages\n\nStructure of \"Published message\":\n``` ts\nconst message = {\n\tproperties?: {\n\t\t// MIME content type\n\t\tcontent_type?: string,\n\t\t// MIME content encoding\n\t\tcontent_encoding?: string,\n\t\t// For applications, and for header exchange routing\n\t\theaders?: object,\n\t\t/**\n\t\t * For queues that implement persistence:\n\t\t * non-persistent (1) or persistent (2)\n\t\t */\n\t\tdelivery_mode?: number,\n\t\t// message priority, 0 to 9\n\t\tpriority?: number,\n\t\t// For application use, correlation identifier\n\t\tcorrelation_id?: string,\n\t\t// address to reply to\n\t\treply_to?: string,\n\t\t// message expiration specification\n\t\texpiration?: string,\n\t\t// application message identifier\n\t\tmessage_id?: string,\n\t\t// message timestamp\n\t\ttimestamp?: Date,\n\t\t// For application use, message type name\n\t\ttype?: string,\n\t\t// creating user id\n\t\tuser_id?: string,\n\t\t// application id\n\t\tapp_id?: string\n\t},\n\t// name of exchange to publish\n\texchange?: string,\n\t// routing key to publish\n\trouting_key?: string,\n\t// callback which is called after current message will published\n\tcallback?: (error?: Error | null, result?: {delivery_tag: bigint, multiple: boolean}) =\u003e void,\n\t// optional body to publish\n\tbody?: Readable | Buffer,\n\t// size of body, required for case when body is stream\n\tbody_size\n}\n```\nThere are 2 ways for publishing messages in the client:\n1. Using writable publisher stream\n2. Using publisher helper\n\nExamples:\n``` ts\nimport {ReadableAsync, pipeline} from '@pieropatron/stream-async';\nimport {createReadStream} from 'fs';\nimport {Client, PublishMessage} from '@pieropatron/amqp-client';\n\n// publish using streams:\nconst rs = new ReadableAsync\u003cPublishMessage\u003e;\nawait rs.pushAsync({\n\tbody: createReadStream(__dirname + '/big.avi'),\n\tcallback: (error, result)=\u003e{\n\t\tconsole.log(error, result);\n\t\trs.push(null);\n\t}\n});\n\nconst publish_writable = await client.publish_writable();\nawait pipeline(rs, publish_writable);\n\n// publish using helper:\nconst publisher = await client.create_publisher();\nawait publisher.publish({\n\tbody: createReadStream(__dirname + '/big.avi'),\n\tcallback: (error, result)=\u003e{\n\t\tconsole.log(error, result);\n\t}\n});\n```\n\n## Consume messages\n\nStructure of \"Consume message\":\n\n``` ts\nconst message = {\n\t// tag of consumer\n    \tconsumer_tag: string,\n    \t// unique (for consumer) delivery number\n    \tdelivery_tag: bigint,\n\t// is message redeliveried\n    \tredelivered: boolean,\n\t// name of source exchange\n    \texchange: string,\n\t// delivery routing key\n    \trouting_key: string,\n\t// same properties structure as for Publish message\n\tproperties?: {},\n\t// Readable stream, with additional method toBuffer (for easy get content, if required)\n\tbody?: ConsumerBodyReadable,\n\t// size of body\n\tbody_size?: number,\n\t// Method to call if message was processed well\n\tack: ()=\u003ePromise\u003cvoid\u003e,\n\t// Method to call if message was processed bad\n\tnack: (requeue: boolean)=\u003ePromise\u003cvoid\u003e\n}\n```\n\nNB: for message it is mandatory to call ack or nack after the process!\n\nExample:\n``` ts\nimport {ConsumeMessage} from '@pieropatron/amqp-client';\nimport {WritableAsync, pipeline} from '@pieropatron/stream-async';\n\nconst consumer_transform = await client.consumer_transform({\n\t/** Queue for consume */\n\tqueue: string,\n\t/** Prefetch count of messages */\n\tprefetch_count: number,\n\t/** Do not receive messages from same connection */\n\tno_local: boolean,\n\t/** Identifier for the consumer */\n\tconsumer_tag: string,\n\t/** In case of set, only this consumer can access the queue. */\n\texclusive: boolean,\n\t/** Priority of consumer. Can be positive or negative. */\n\tpriority: number,\n\t// Any other supported consume arguments\n\tcustom: Record\u003cstring, any\u003e\n});\n\nawait pipeline(\n\tconsumer_transform,\n\tnew WritableAsync\u003cConsumeMessage\u003e({\n\t\tasync write(chunk: ConsumeMessage){\n\t\t\tif (chunk.body){\n\t\t\t\tconst buffer = await chunk.body.toBuffer();\n\t\t\t\tconsole.log(buffer.toString());\n\t\t\t\tawait chunk.ack();\n\t\t\t} else {\n\t\t\t\tawait chunk.nack(false);\n\t\t\t}\n\t\t}\n\t})\n);\n```\n\nThat's all for this client. Hope, it will be usefull for you.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpieropatron%2Famqp-client","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fpieropatron%2Famqp-client","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpieropatron%2Famqp-client/lists"}