{"id":15013451,"url":"https://github.com/aadamsx/fine-rest","last_synced_at":"2025-07-08T22:04:11.512Z","repository":{"id":57236427,"uuid":"96849007","full_name":"aadamsx/fine-rest","owner":"aadamsx","description":"fine-rest: make your app accessible over HTTP and DDP","archived":false,"fork":false,"pushed_at":"2017-07-28T03:31:10.000Z","size":1583,"stargazers_count":10,"open_issues_count":1,"forks_count":0,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-07-01T11:08:49.370Z","etag":null,"topics":["javascript-library","json-api","meteorjs","npm-package","rest-api","webapi"],"latest_commit_sha":null,"homepage":"https://www.npmjs.com/package/fine-rest","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/aadamsx.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE.md","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2017-07-11T03:59:41.000Z","updated_at":"2024-04-01T13:35:04.000Z","dependencies_parsed_at":"2022-08-23T16:20:15.031Z","dependency_job_id":null,"html_url":"https://github.com/aadamsx/fine-rest","commit_stats":null,"previous_names":[],"tags_count":1,"template":false,"template_full_name":null,"purl":"pkg:github/aadamsx/fine-rest","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/aadamsx%2Ffine-rest","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/aadamsx%2Ffine-rest/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/aadamsx%2Ffine-rest/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/aadamsx%2Ffine-rest/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/aadamsx","download_url":"https://codeload.github.com/aadamsx/fine-rest/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/aadamsx%2Ffine-rest/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":264357294,"owners_count":23595575,"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":["javascript-library","json-api","meteorjs","npm-package","rest-api","webapi"],"created_at":"2024-09-24T19:44:18.028Z","updated_at":"2025-07-08T22:04:11.485Z","avatar_url":"https://github.com/aadamsx.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"\n# This is [fine-rest](https://www.npmjs.com/package/fine-rest)\n\n#### A fine way to define REST server-side routes in Meteor.\n##### Make your Meteor app's data accessible over HTTP. Integrate your Meteor backend into a native mobile app or just query your data over HTTP from any client.\n---\nInstall fine-rest in your Meteor project via npm:\n\n```bash\n$ meteor npm install --save fine-rest\n```\n\nNow use fine-rest in project like so:\n\n```javascript\nimport { JsonRoutes } from 'fine-rest';\n```\n\nA Meteor example application using fine-rest:\n\n\n### [Meteor Web API Example](https://github.com/aadamsx/meteor-web-app-test)\n\n\n---\n\n### This package was formally the following Meteor packages, their functionality now rolled into one fine NPM package:\n\n### [json-routes](#json-routes-1)\n### [authenticate-user-by-token](#authenticate-user-by-token-1)\n### [rest-accounts-password](#rest-accounts-password-1)\n### [rest-bearer-token-parser](#rest-bearer-token-parser-1)\n### [rest-json-error-handler](#rest-json-error-handler-1)\n\n...\n### [Change Log](#change-log-1)\n\n---\n\n\n# json-routes\n\nA bare-bones way to define server-side JSON API endpoints, without\nany extra functionality. Based on [connect-route].\n\n### Example\n\n```js\nJsonRoutes.add(\"get\", \"/posts/:id\", function (req, res, next) {\n  var id = req.params.id;\n\n  JsonRoutes.sendResult(res, {\n    data: Posts.findOne(id)\n  });\n});\n```\n\n## API\n\n### JsonRoutes.add(method, path, handler)\n\nAdd a server-side route that returns JSON.\n\n- `method` - The HTTP method that this route should accept: `\"get\"`, `\"post\"`,\n  etc. See the full list [here][connect-route L4]. The method name is\n  case-insensitive, so `'get'` and `'GET'` are both acceptable.\n- `path` - The path, possibly with parameters prefixed with a `:`. See the\n  example.\n- `handler(request, response, next)` - A handler function for this route.\n  `request` is a Node request object, `response` is a Node response object,\n  `next` is a callback to call to let the next middleware handle this route. You\n  don't need to use this normally.\n\n### JsonRoutes.sendResult(response, options)\n\nReturn data fom a route.\n\n- `response` - Required. The Node response object you got as an argument to your handler function.\n- `options.code` - Optional. The status code to send. `200` for OK, `500` for internal error, etc. Default is 200.\n- `options.headers` - Optional. Dictionary of headers to send back.\n- `options.data` - Optional. The data you want to send back. This is serialized to JSON with content type `application/json`. If `undefined`, there will be no response body.\n\n## Errors\n\nWe recommend that you simply throw an Error or Meteor.Error from your handler function. You can then attach error handling middleware that converts those errors to JSON and sends the response. Here's how to do it with our default error middleware:\n\n```js\nJsonRoutes.ErrorMiddleware.use(\n  '/widgets',\n  RestMiddleware.handleErrorAsJson\n);\n\nJsonRoutes.add('get', 'widgets', function () {\n  var error = new Meteor.Error('not-found', 'Not Found');\n  error.statusCode = 404;\n  throw error;\n});\n```\n\n### JsonRoutes.setResponseHeaders(headerObj)\n\nSet the default headers used by `JsonRoutes.sendResult` for the response. Default value is:\n\n```js\n{\n  \"Cache-Control\": \"no-store\",\n  \"Pragma\": \"no-cache\"\n}\n```\n\nYou can pass additional headers directly to `JsonRoutes.sendResult`\n\n## Adding Middleware\n\nIf you want to insert connect middleware and ensure that it runs before your\nREST route is hit, use `JsonRoutes.Middleware`.\n\n```js\nJsonRoutes.Middleware.use(function (req, res, next) {\n  console.log(req.body);\n  next();\n});\n```\n\n## Creating Middleware Packages\n\nOnce you've created an awesome piece of reusable middleware and you're ready to\nshare it with the world, you should make it a Meteor package so it can be easily\nconfigured in any JSON Routes API. There are only two requirements.\nActually, they're just very strong recommendations. Nothing will explode if you\ndon't follow these guidelines, but doing so should promote a much cleaner\nmiddleware ecosystem.\n\nEach middleware package should define a single middleware function and add it\nto `RestMiddleware` namespace:\n\n```js\nRestMiddleware.someMiddlewareFunc = function (req, res, next) {\n  // Do some awesome middleware stuff here\n};\n\nRestMiddleware.someMiddlewareErrorFunc = function (err, req, res, next) {\n  // Do some awesome middleware error handling here\n};\n```\n\nAlternatively, you could publish a pure NodeJS middleware package to NPM, and you will be able to require it and use it in your Meteor package or app.\n\n### Auth Middleware\n\n- By convention, any middleware you create that parses the request to find an authentication token should then save that token on `req.authToken`. See `rest-bearer-token-parser` for an example.\n- By convention, any middleware you create that determines a user ID should save that ID on `req.userId`. See `authenticate-user-by-token` for an example.\n\n---\n\n# authenticate-user-by-token\nMiddleware for validating a Meteor.user's login token\n\n## Middleware Name\n\nThis middleware can be accessed as:\n\n**`JsonRoutes.Middleware.authenticateMeteorUserByToken`**\n\n### Request Properties Required\n\n- `request.authToken`\n  - _String_\n  - A valid login token for a `Meteor.user` account (requires `accounts-base`)\n\n### Request Properties Modified\n\n- `request.userId`\n  - _String_\n  - If the `request.authToken` is found in a user account, sets this to the ID of the authenticated user. Otherwise, `null`.\n\n## Usage\n\nSimply add this layer of middleware after any token parsing middleware, and voila!\n\nFor example:\n\n```js\nJsonRoutes.Middleware.use('/auth', JsonRoutes.Middleware.parseBearerToken);\nJsonRoutes.Middleware.use('/auth', JsonRoutes.Middleware.authenticateMeteorUserByToken);\n\nJsonRoutes.add('GET', 'auth/test', function (request, response) {\n  // The authenticated user's ID will be set by this middleware\n  var userId = request.userId;\n});\n```\n\n---\n\n# rest-accounts-password\n\n## Log in and register password accounts over HTTP\n\nIf you have `accounts-password` in your app, and you want to be able to use it over HTTP, this is the package for you. Call these APIs to get an access token, and pass that token to API methods you defined with [`json-routes`](#json-routes-1) to call methods and publications that require login.\n\nMake sure to serve your app over HTTPS if you are using this for login, otherwise people can hijack your passwords. Try the [`force-ssl` package](https://atmospherejs.com/meteor/force-ssl).\n\n### POST /users/login, POST /users/register, POST /users/token-login\n\nThe login and registration endpoints take the same inputs. Pass an object with the following properties:\n\n- `username`\n- `email`\n- `password`\n- `dbId`\n\n`password` is required, and you must have at least one of `username` or `email`.  dbId is optional and for multi-database scenarios.\n\nThe token-login endpoint only requires a token and optionally a Database ID.\n\n- `dbId`\n- `loginToken`\n\n#### Responses\n\nBoth login and registration have the same response format.\n\n```js\n// successful response, with HTTP code 200\n{\n  token: \"string\",\n  tokenExpires: \"ISO encoded date string\",\n  id: \"user id\"\n}\n\n// error response, with HTTP code 500\n{\n  error: \"error-code\",\n  reason: \"Human readable error string\"\n}\n```\n\n### Authentication\n\nAfter adding this package, API endpoints accept a standard bearer token header (Based on [RFC 6750](http://tools.ietf.org/html/rfc6750#section-2.1) and [OAuth Bearer](http://self-issued.info/docs/draft-ietf-oauth-v2-bearer.html#authz-header)).\n\n```http\nAuthorization: Bearer \u003ctoken\u003e\n```\n\nHere is how you could use Meteor's `http` package to call a method as a logged in user. Inside the method, the current user can be accessed the exact same way as in a normal method call, through `this.userId`.\n\n```js\nHTTP.post(\"/methods/return-five-auth\", {\n  headers: { Authorization: \"Bearer \" + token }\n}, function (err, res) {\n  console.log(res.data); // 5\n});\n```\n\n---\n\n# rest-bearer-token-parser\n\nMiddleware for parsing a standard bearer token from an HTTP request\n\n### Middleware Name\n\nThis middleware can be accessed as:\n\n**`JsonRoutes.Middleware.parseBearerToken`**\n\n### Request Properties Required\n\n- None\n\n### Request Properties Modified\n\n- `request.authToken`\n  - _String_\n  - The parsed bearer token, or `null` if none is found\n\n## Usage\n\nAccepts tokens passed via the standard header or URL query parameter (whichever is found first, in that order).\n\nThe header signature is: `Authorization: Bearer \u003ctoken\u003e`\n\nThe query signature is: `?access_token=\u003ctoken\u003e`\n\n---\n\n## rest-json-error-handler\n\nMiddleware for converting thrown Meteor.Errors to JSON and sending the response.\n\n## Usage\n\nHandle errors from all routes:\n\n```js\nJsonRoutes.ErrorMiddleware.use(RestMiddleware.handleErrorAsJson);\n```\n\nHandle errors from one route:\n\n```js\nJsonRoutes.ErrorMiddleware.use(\n  '/handle-error',\n  RestMiddleware.handleErrorAsJson\n);\n```\n\n## Example\n\n```js\nJsonRoutes.ErrorMiddleware.use(\n  '/handle-error',\n  RestMiddleware.handleErrorAsJson\n);\n\nJsonRoutes.add('get', 'handle-error', function () {\n  var error = new Meteor.Error('not-found', 'Not Found');\n  error.statusCode = 404;\n  throw error;\n});\n```\n\n\n\n---\n\n# Change Log\n\n#### 2.0.0\n\n- Added ability to log in with token at ```/users/token-login```.\n- Pass in an optional Database ID for multi database scenarios to ```/users/login```.\n- The log in option ```/users/login``` now has the option to pass in a Database ID for multi database scenarios.\n- Use the setting.json file in your root project to specify your database ID.\n\n#### 1.0.0 - 1.0.12\n\n- Refactored code and converted over `JsonRoutes` \u0026 related packages to NPM fine-rest\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Faadamsx%2Ffine-rest","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Faadamsx%2Ffine-rest","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Faadamsx%2Ffine-rest/lists"}