{"id":13527433,"url":"https://github.com/argo/argo","last_synced_at":"2025-04-23T16:30:51.158Z","repository":{"id":5677145,"uuid":"6887076","full_name":"argo/argo","owner":"argo","description":"Argo is a modular HTTP gateway for Web APIs.","archived":false,"fork":false,"pushed_at":"2020-07-21T03:16:43.000Z","size":326,"stargazers_count":87,"open_issues_count":13,"forks_count":7,"subscribers_count":15,"default_branch":"master","last_synced_at":"2025-04-15T10:45:51.192Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"JavaScript","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/argo.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}},"created_at":"2012-11-27T16:47:11.000Z","updated_at":"2025-01-02T01:10:30.000Z","dependencies_parsed_at":"2022-08-24T17:42:02.800Z","dependency_job_id":null,"html_url":"https://github.com/argo/argo","commit_stats":null,"previous_names":[],"tags_count":5,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/argo%2Fargo","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/argo%2Fargo/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/argo%2Fargo/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/argo%2Fargo/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/argo","download_url":"https://codeload.github.com/argo/argo/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":250470880,"owners_count":21435855,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","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":[],"created_at":"2024-08-01T06:01:47.840Z","updated_at":"2025-04-23T16:30:50.850Z","avatar_url":"https://github.com/argo.png","language":"JavaScript","readme":"# Argo\n\nAn extensible, asynchronous HTTP reverse proxy and origin server.\n\n\u003c!-- Argo is:\n\n* An API-focused HTTP server.\n* A reverse proxy to manage and modify HTTP requests and responses.\n* Modular using handlers for request and response pipelines.\n* Extensible using a package system.\n\nAs an API server:\n\n* Route requests to handlers.\n* Separate resources into modules.\n\nAs a reverse proxy:\n\n* Route requests to backend servers.\n* Transform HTTP messages on the fly.\n* Add OAuth 2.0 support to an existing API.\n* Create a RESTful API façade over legacy systems.\n--\u003e\n\n## Examples\n\n### Adding Cross-Origin Resource Sharing\n\nSetup the server:\n\n```javascript\nvar argo = require('argo');\n\nargo()\n  .use(function(handle) {\n    handle('response', function(env, next) {\n      env.response.setHeader('Access-Control-Allow-Origin', '*');\n      next(env);\n    });\n  })\n  .target('http://weather.yahooapis.com')\n  .listen(1337);\n```\n\nMake a request:\n\n```bash\n$ curl -i http://localhost:1337/forecastrss?w=2467861\n\nHTTP/1.1 200 OK\nDate: Thu, 28 Feb 2013 20:55:03 GMT\nContent-Type: text/xml;charset=UTF-8\nConnection: keep-alive\nServer: YTS/1.20.13\nAccess-Control-Allow-Origin: *\nContent-Length: 2337\n\n\u003c?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\" ?\u003e\n\u003cGiantXMLResponse/\u003e\n```\n\n### Serving an API Response \n\nSetup the server: \n\n```javascript\nvar argo = require('argo');\n\nargo()\n  .get('^/dogs$', function(handle) {\n    handle('request', function(env, next) {\n      env.response.statusCode = 200;\n      env.response.body = { dogs: ['Alfred', 'Rover', 'Dino'] };\n      next(env);\n    });\n  })\n  .listen(1337);\n```\n\nMake a request:\n\n```bash\n$ curl -i http://localhost:1337/dogs\n\nHTTP/1.1 200 OK\nContent-Type: application/json\nContent-Length: 34 \nDate: Thu, 28 Feb 2013 20:44:46 GMT\nConnection: keep-alive\n\n{\"dogs\":[\"Alfred\",\"Rover\",\"Dino\"]}\n```\n\n## Install\n\n```bash\n$ npm install argo\n```\n\n## Documentation\n\n* [handleFunction](#handleFunction)\n* [use(handleFunction)](#usehandle)\n* [use(package)](#usepackage)\n* [target](#target)\n* [route](#route)\n* Method filters\n  * [get](#get)\n  * [post](#post)\n  * [put](#put)\n  * [head](#head)\n  * [del](#del)\n  * [options](#options)\n  * [trace](#trace)\n  * [copy](#copy)\n  * [lock](#lock)\n  * [mkcol](#mkcol)\n  * [move](#move)\n  * [propfind](#propfind)\n  * [proppatch](#proppatch)\n  * [unlock](#unlock)\n  * [report](#report)\n  * [mkactivity](#mkactivity)\n  * [checkout](#checkout)\n  * [merge](#merge)\n  * [msearch](#msearch)\n  * [notify](#notify)\n  * [subscribe](#subscribe)\n  * [unsubscribe](#unsubscribe)\n  * [patch](#patch)\n  * [search](#search)\n* [map](#map)\n* [include](#include)\n* [listen](#listen)\n* [Error Handling](#error-handling)\n\n\n## Usage\n\n\u003ca name=\"handleFunction\"/\u003e\n### handleFunction(type, [options], callback)\n\n* `type`: `'request'` or `'response'`\n\n* `options`: Mostly used for internal purposes.  Optional.\n\n* `callback(env, next)`: A request or response callback. `env` is an environment context that is passed to every handler, and `next` is a reference to the next function in the pipeline.\n\nWhen the handler is complete and wishes to pass to the next function in the pipeline, it must call `next(env)`.\n\n\u003ca name=\"usehandle\"/\u003e\n### use(handleFunction)\n\n`handleFunction` is used to set up request and response handlers.  \n\n```javascript\nargo()\n  //For every request add 'X-Custom-Header' with value 'Yippee!'\n  .use(function(handle) {\n    handle('request', function(env, next) {\n      env.request.headers['X-Custom-Header'] = 'Yippee!';\n      next(env);\n    });\n  })\n```\n\u003ca name=\"usepackage\"/\u003e\n### use(package)\n\nAlias for `include(package)`.\n\n\u003ca name=\"target\"/\u003e\n### target(uri)\n\n`target` is used for proxying requests to a backend server.\n\n* `uri`: a string pointing to the target URI.\n\nExample:\n\n```javascript\nargo()\n  .target('http://weather.yahooapis.com')\n```\n\u003ca name=\"route\"/\u003e\n### route(path, [options], handleFunction)\n\n* `path`: a regular expression used to match HTTP Request URI path.\n\n* `options`: an object with a `methods` property to filter HTTP methods (e.g., `{ methods: ['GET','POST'] }`).  Optional.\n\n* `handleFunction`: Same as in `use`.\n\nExample:\n\n```javascript\nargo()\n  .route('^/greeting$', function(handle) {\n    handle('request', function(env, next) {\n      env.response.statusCode = 200;\n      env.response.headers = { 'Content-Type': 'text/plain' };\n      env.response.body = 'Hello World!';\n \n      next(env);\n    });\n  })\n```\n\n### Method filters\n\u003ca name=\"get\"/\u003e\n\u003ca name=\"post\"/\u003e\n\u003ca name=\"put\"/\u003e\n\u003ca name=\"head\"/\u003e\n\u003ca name=\"del\"/\u003e\n\u003ca name=\"options\"/\u003e\n\u003ca name=\"trace\"/\u003e\n\u003ca name=\"copy\"/\u003e\n\u003ca name=\"lock\"/\u003e\n\u003ca name=\"mkcol\"/\u003e\n\u003ca name=\"move\"/\u003e\n\u003ca name=\"propfind\"/\u003e\n\u003ca name=\"proppatch\"/\u003e\n\u003ca name=\"unlock\"/\u003e\n\u003ca name=\"report\"/\u003e\n\u003ca name=\"mkactivity\"/\u003e\n\u003ca name=\"checkout\"/\u003e\n\u003ca name=\"merge\"/\u003e\n\u003ca name=\"msearch\"/\u003e\n\u003ca name=\"notify\"/\u003e\n\u003ca name=\"subscribe\"/\u003e\n\u003ca name=\"unsubscribe\"/\u003e\n\u003ca name=\"patch\"/\u003e\n\u003ca name=\"search\"/\u003e\n#### get(path, handleFunction)\n#### post(path, handleFunction)\n#### put(path, handleFunction)\n#### head(path, handleFunction)\n#### del(path, handleFunction)\n#### options(path, handleFunction)\n#### trace(path, handleFunction)\n#### copy(path, handleFunction)\n#### lock(path, handleFunction)\n#### mkcol(path, handleFunction)\n#### move(path, handleFunction)\n#### propfind(path, handleFunction)\n#### proppatch(path, handleFunction)\n#### unlock(path, handleFunction)\n#### report(path, handleFunction)\n#### mkactivity(path, handleFunction)\n#### checkout(path, handleFunction)\n#### merge(path, handleFunction)\n#### msearch(path, handleFunction)\n#### notify(path, handleFunction)\n#### subscribe(path, handleFunction)\n#### unsubscribe(path, handleFunction)\n#### patch(path, handleFunction)\n#### search(path, handleFunction)\n\nMethod filters built on top of `route`. `del` and `msearch` correspond to\nthe DELETE and M-SEARCH methods, respectively.\n\nExample:\n\n```javascript\nargo()\n  .get('^/puppies$', function(handle) {\n    handle('request', function(env, next) {\n      env.response.body = JSON.stringify([{name: 'Sparky', breed: 'Fox Terrier' }]);\n      next(env);\n    });\n  })\n```\n\n\u003ca name=\"map\"/\u003e\n### map(path, [options], argoSegmentFunction)\n\n`map` is used to delegate control to sub-Argo instances based on a request URI path.\n\n* `path`: a regular expression used to match the HTTP Request URI path.\n\n* `options`: an object with a `methods` property to filter HTTP methods (e.g., `{ methods: ['GET','POST'] }`).  Optional.\n\n* `argoSegmentFunction`: a function that is passed an instance of `argo` for additional setup.\n\nExample:\n\n```javascript\nargo()\n  .map('^/payments', function(server) {\n    server\n      .use(oauth)\n      .target('http://backend_payment_server');\n  })\n```\n\u003ca name=\"include\"/\u003e\n### include(package)\n\n* `package`: An object that contains a `package` property.\n\nThe `package` property is a function that takes an argo instance as a paramter and returns an object that contains a `name` and an `install` function.\n\nExample:\n\n```javascript\nvar superPackage = function(argo) {\n  return {\n    name: 'Super Package',\n    install: function() {\n      argo\n        .use(oauth)\n        .route('^/super$', require('./super'));\n    }\n  };\n};\n\nargo()\n  .include({ package: superPackage})\n```\n\u003ca name=\"listen\"/\u003e\n### listen(port)\n\n* `port`: A port on which the server should listen.\n\n\u003ca name=\"error-handling\"/\u003e\n### Error Handling\n\nArgo allows a special `error` handler for capturing state when an uncaught exception occurs.\n\n```javascript\nargo()\n  .use(function(handle) {\n    handle('error', function(env, error, next) {\n      console.log(error.message);\n      env.response.statusCode = 500;\n      env.response.body = 'Internal Server Error';\n      next(env);\n      process.exit();\n    });\n  })\n  .get('^/$', function(handle) {\n    handle('request', function(env, next) {\n      env.response.body = 'Hello World!';\n      next(env);\n    });\n  })\n  .get('^/explode$', function(handle) {\n    handle('request', function(env, next) {\n      setImmediate(function() { throw new Error('Ahoy!'); });\n    });\n  })\n  .listen(3000);\n```\n\nUnlike other named pipelines, there should be only one error handler assigned to an Argo server. It is recommended to exit the process once an error has been handled. This feature uses [domains](http://nodejs.org/api/domain.html).\n\nSee [`cluster.js`](https://github.com/argo/argo/blob/master/example/cluster.js) for an example of using error handling to restart workers in a cluster.\n\n## Tests\n\nUnit tests: \n\n```bash\n$ npm test\n```\n\nTest Coverage:\n\n```bash\n$ npm run-script coverage\n```\n\n## License\nMIT\n","funding_links":[],"categories":["Repository"],"sub_categories":["HTTP"],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fargo%2Fargo","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fargo%2Fargo","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fargo%2Fargo/lists"}