feathersjs-ecosystem / feathers-rest Goto Github PK
View Code? Open in Web Editor NEWThe Feathers HTTP(S) transport plugin for REST APIs
License: MIT License
The Feathers HTTP(S) transport plugin for REST APIs
License: MIT License
webpack 1/2, node 7.1.0
Every time I'm trying to use the module on the client side I'm getting the error. Has anybody run into this issue?
The error
Uncaught TypeError: fn.call is not a function(…)
Deps:
"dependencies": {
"feathers": "^2.0.2",
"feathers-rest": "^1.5.2"
},
"devDependencies": {
"babel-core": "^6.18.2",
"babel-loader": "^6.2.8",
"babel-preset-es2015": "^6.18.0",
"babel-preset-stage-0": "^6.16.0",
"webpack": "^2.1.0-beta.27"
}
Webpack config:
const path = require('path');
const SRC = path.resolve('./src');
const BUILD = path.resolve('./build');
module.exports = {
context: SRC,
entry: {
vendor: [],
main: './'
},
output: {
path: BUILD,
filename: '[name].bundle.js',
publicPath: '/assets/'
},
module: {
loaders: [{
test: /\.js$/,
include: SRC,
loader: 'babel-loader'
}]
},
devServer: {
contentBase: BUILD,
proxy: {
"*": "http://localhost:3000"
}
}
};
.babelrc
{
"presets": ["es2015", "stage-0"]
}
Client code:
const feathers = require('feathers/client');
const rest = require('feathers-rest/client');
const app = feathers()
.configure(rest());
There may be cases where a request comes in as an id request so it would use get but you want to change it to use find so you can test other properties on that data before requesting it by moving the id into the find query and setting the hook.method = 'find'.
For instance:
find({ query: {id: '0', approved: true} })
Here we want to query the id but we only want approved true. In this case don't want to filter the data afterward because it's needless work on the database.
When using feathers-rest the Accept: application/json
-Header is not set by default.
Since it is required to get the right errors from the backend I propose to add them as a default.
From the docs
ProTip: If you want to have the response in json format be sure to set the
Accept
header in your request toapplication/json
otherwise the default error handler will return HTML.
Hi @daffl
I would like to return the custom HTTP status. For example with PUT method, when create new entity, I will return code 201. When update existing entity then I will return the code of 200.
How can I return the custom status code with feathers-rest?
One think I see that we can pass the res object into params in wrappers.js so that we can freely set status code for our needs.
What do you think ?
Branch | Build failing 🚨 |
---|---|
Dependency | feathers |
Current Version | 2.1.7 |
Type | devDependency |
This version is covered by your current version range and after updating it in your project the build failed.
As feathers is “only” a devDependency of this project it might not break production or downstream projects, but “only” your build or test tools – preventing new deploys or publishes.
I recommend you give this issue a high priority. I’m sure you can resolve this 💪
The new version differs by 7 commits.
aa87658
2.2.0
1738993
Update package-lock.json
7422757
No longer pollutes the global scope (#662)
a28ec8e
fix(package): update debug to version 3.0.0 (#641)
e317dd5
Examples url is tinny (broken) (#634)
b57c80b
Merge pull request #624 from jansel369/master
8f40769
Adds a missing configure() method in typescript difinition
See the full diff
There is a collection of frequently asked questions and of course you may always ask my humans.
Your Greenkeeper Bot 🌴
Send the request to the base URL if the id is null
.
axios is becoming super popular these days. It would be nice if feathers-rest
also support axios
.
This is particularly useful if you want to handle error differently based on the hook.method
that was called (ie. render a template, or redirect).
Register a custom error middleware after a service.
app.use('/users', userService, function(error, req, res, next) {
// res.hook should be defined.
});
res.hook
should be defined.
It is not.
Tell us about the applicable parts of your setup.
Module versions (especially the part that's not working): [email protected]
These lines need to move up above this line.
In reference to this discussion feathersjs-ecosystem/feathers-sequelize#12 there is now a sequelize parameter for feathers-sequelize. However when using the rest client, this parameter is never send to the server.
See here: https://github.com/feathersjs/feathers-rest/blob/master/src/client/base.js#L36
I admit i didn't testet it yet on the server side, however i guess there it might work. But still i should be able to do this on the client as well right?
example:
feathers().service("myService").find({
sequelize: {
include: [{ all: true }]
}
}).then(myPreciousRelations=> {
console.log(myPreciousRelations);
});
Primarily this is required for authentication to work because we want to set the Authorization
header.
The service and hooks abstraction in feathers is awesome and really powerful. So much in fact, that I want to use it more extensively. I want to be able to create internal only services that have useful server side logic like a file storage service or a field validator service.
The problem becomes that I have to expose that service's CRUD methods as rest methods. I don't necessarily want to do that. So far I have taken to namespacing my internal services with an service_name. This is obviously not an ideal solution.
Having peeked into the logic that hooks a service up to express, it seems like it wouldn't be hard to just skip that part if some flag is set on the service, or if the name is service_name or some other construct.
Thanks!
I want to use axios as my ajax tool:
const app = feathers()
.configure(rest('http://baseUrl').axios(axios))
But there is an error: Property 'axios' does not exist on type 'Transport'
, I check the client.d.ts
as follows:
interface Transport {
jquery: Handler;
superagent: Handler;
request: Handler;
fetch: Handler;
}
find there is no axios here.
It needs to be set explicitly using .set('Accept', 'application/json')
.
To prepare for feathers v3, feathers-rest should either be renamed: feathers-rest-express or be moved into feathers core in a separate folder that is exported under the rest
namespace. The same should be done for other http framework integrations/foundations such as Koa, Hapi etc.
From slack:
Chrome throws an error `TypeError: Ilegal invocation`.
While firefox `TypeError: 'fetch' called on an object that does not implement interface Window.`
The REST base client should have a safeguard checking for id === undefined
for remove
, update
and patch
so that things like .remove(mydata.id)
don't accidentally remove the entire collection if mydata.id
is undefined.
Instead of params
directly.
When creating or updating a resource, a Location
header with a value of /<service>/:id
should be set by default. Thanks in advance.
Hey,
I'm currently trying to implement that if the Accept header is "application/vnd.api+json" a json-api (http://jsonapi.org/) conform response is send back. First I was thinking about cloning feathers-rest and modifying it but it won't work as feathers-rest would still catch all GET, POST, PUT, etc. calls in my understanding. So there is no way to do it that clean (or is it?).
So now I'm think about rewriting the response in the formatter to be json-api conform but it feels a little bit hacky after all.
What do you think? What is the best way in you opinion?
Greets,
Nico
This is a follow-up for feathersjs/feathers#135 but not extremely high priority at the moment since we added pagination to all our service adapters.
I'd like to add better support for pagination and something similar to GitHubs Link:
HTTP headers (see here) like:
Link: <https://api.github.com/search/code?q=addClass+user%3Amozilla&page=15>; rel="next",
<https://api.github.com/search/code?q=addClass+user%3Amozilla&page=34>; rel="last",
<https://api.github.com/search/code?q=addClass+user%3Amozilla&page=1>; rel="first",
<https://api.github.com/search/code?q=addClass+user%3Amozilla&page=13>; rel="prev"
This actually shouldn't be too hard to implement and backwards compatible. All we need to do is have service.find
return an object with information about it's pagination data (you should use an object with { "data": [] }
anyway for security reasons):
/// /todos
{
"total": 1000,
"limit": 20,
"skip": 40,
"data": []
}
Our quasi standard is to use $
for query parameters like $limit=10&$start=20
. Then we would know how to generate a link header like:
Link: <http://feathersjs.com/todos?$limit=20&$start=19>; rel="next",
<http://feathersjs.com/todos?$limit=20&$start=979>; rel="last"
If we make the pre-built services support this out of the box it will be really nice to use (I had to code this manually a couple of times already).
This is too common of a request to not be next on the list. There are a lot of headers that match between the transports: https://gist.github.com/marshallswain/b775c7b6d7a9b2429b0eb6fe669a2bfd
Currently the auth plugin has the expose-headers middleware, but I think we should move it here and and the remote IP address on the feathers object, as well.
app.use(function (req, res, next) {
req.feathers.headers = req.headers;
req.feathers.ip = req.ip;
next();
});
I'd do a PR, but hardly seems worth it since a maintainer can edit the file right in github... :-)
The link to providers docs in README.md is 404'ing:
https://github.com/feathersjs/feathers-rest/blame/master/README.md#L11
I think it's supposed to be this:
http://docs.feathersjs.com/rest/readme.html
With the current client it's not that easy to upload files. You can't quite do a create
via the rest client. Instead you need to use the underlying library. I'm a big fan of how superagent handles multipart requests.
I think we should consider one of 3 options:
create
call, orattach
method that allows you to add files for a create call.Hi,
when i use angular (4) http client i am stucked on exception from HttpXsrfInterceptor.intercept function (row 76) req.url.toLowerCase is not a function.
https://github.com/angular/angular/blob/4.4.6/packages/common/http/src/xsrf.ts
i know that i am using new HttpClient implementation but with an old Http (client) it throws the same exception.
Should work? =)
Throws an exception req.url.toLowerCase is not a function
In a Feathers server I had set up a service for uploading images following the official guide on file uploads, using multer
as middleware and all.
The code is exactly the same as that tutorial, https://docs.feathersjs.com/guides/advanced/file-uploading.html, because it works when I use Postman to test it.
In the client I use react-dropzone
to get a file due for uploading, and found out that the reason why multer
doesn't process the image is because the content-type
header isn't being set accordingly. It needs to be in a format of: multipart/form-data --==...
Now, this cannot be achieved by hooks.
'content-type': 'multipart/form-data'
results in the server receiving: 'content-type': 'application/json, multipart/form-data',
.boundary=----WebKitFormBoundaryDKc3PiteTDBUUMlm
results in the server content-type header as 'application/json, multipart/form-data; boundary=----WebKitFormBoundaryDKc3PiteTDBUUMlm'
which you'd expect to work, but it turns out it doesn't, multer
doesn't run. It appears to be a parameter that isn't supposed to be manually put in.It should be noted that Postman does this automatically, when you try to override the request header there with a simple 'content-type':'multipart/form-data' the boundary parameter will not be supplied, thus an error. So in Postman I did not supply any headers, and the Feathers upload service simply works, I can see the proper header being received as well.
Upon research I found that if you're using forms in React, you can use the encType
property to set the content type properly, and it will trigger. But I wasn't using a form, I was doing a service .create(...)
call.
superagent
has something like this: http://visionmedia.github.io/superagent/#setting-the-content-type, but how does one achive this with Feathers?
Module versions (especially the part that's not working):
In the server:
[email protected]
[email protected]
[email protected]
[email protected]
[email protected]
[email protected]
[email protected]
[email protected]
Client side:
[email protected]
[email protected]
[email protected]
[email protected]
NodeJS version:
6.9.1
Operating System:
Windows 10
Browser Version:
Latest Chrome
Module Loader:
For the client:
[email protected]
[email protected]
[email protected]
To the HTTP methods the service supports. See http://greenbytes.de/tech/webdav/rfc2616.html#rfc.section.14.7
Hi,
Sorry to put an issue but I don't have found a response to my answer.
Can you say me how I can return a file instead of data in a service method ?
I have tried to access on the express request method but it doesn't work... Do you know how I can make it ?
Version
feathers-rest: 1.2.3
node: 6.11.1
npm: 5.3.0
Server configuration
require('source-map-support').install() //For mapping errors from es5 to es6
import feathers from 'feathers'
import rest from 'feathers-rest'
import bodyParser from 'body-parser'
import services from './services'
import hooks from 'feathers-hooks'
import configuration from 'feathers-configuration'
import sequelize from './db'
import swaggerObject from '../api/2.0/swagger.json'
import jwtCheck from './middlewares/jwtCheckMiddleware'
import {handler} from './modules/errors/handler'
import uaparser from 'ua-parser-js'
import {default as logger, errorLog} from './lib/logger'
// import AWS from 'aws-sdk'
import validationErrorHandler from './middlewares/validationErrorHandler'
import compression from 'compression'
import packageJson from '../package.json'
import config from './config'
import environmentMiddleware from './middlewares/environmentMiddleware'
let initializeSwagger = require('swagger-tools').initializeMiddleware
sequelize.authenticate()
.then(() => console.log('Connection has been established successfully.'))
.catch((e) => console.error('Unable to connect to the database', {error: e}))
// Configure non-Swagger related middleware and server components prior to Swagger middleware
initializeSwagger(swaggerObject, (swaggerMiddleware) => {
let app = feathers()
app.use(bodyParser.json({limit: '5mb'}))
app.use(environmentMiddleware)
app.use(swaggerMiddleware.swaggerRouter({controllers: './dist/services'}))
// Interpret Swagger resources and attach metadata to request - must be first in swagger-tools middleware chain
app.use(swaggerMiddleware.swaggerMetadata())
// Provide the security handlers
app.use(swaggerMiddleware.swaggerSecurity({
oauth2: (req, def, scopes, callback) => {
}
}))
// Validate Swagger requests
app.use(swaggerMiddleware.swaggerValidator({validateResponse: false}))
// Return custom headers
app.use((req, res, next) => {
res.header("Access-Control-Allow-Origin", "*")
res.header("Access-Control-Allow-Methods", "POST, GET, PUT, DELETE, OPTIONS")
res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept, Authorization, x-g8-device-name, x-g8-device-Uid, X-g8-masterkey, x-g8-environment, x-g8-device-uid, x-g8-refresh-token")
res.header("x-powered-by", `g8 ${packageJson.version}`)
next()
})
// Compress all requests
app.use(compression())
// Serve the Swagger documents and Swagger UI
app.use(swaggerMiddleware.swaggerUi({swaggerUi: "/swagger"}))
app.configure(rest())
.use(jwtCheck)
.use(services)
.use((req, res, next) => {
req.feathers.useragent = uaparser(req.headers['user-agent'])
next()
})
.use((req, res, next) => {
req.feathers.headers = req.headers
next()
})
.configure(hooks())
.configure(configuration(__dirname, 'config'))
//intercept swagger validation tool errors
app.use(validationErrorHandler)
app.use(handler)
app.listen(3000)
})
Invoice service
export default {
/**
* @description Download user company order invoice
* @param data - passed data from request
* @param params - params send with the request
* @param callback
* @returns {Promise}
*/
create(data, params, callback){
// how to return a pdf download file ?
},
setup(app, path){
this.app = app
//Bind the apps service method to service to always look services up dynamically
this.service = app.service.bind(app)
let h = (service) => {
return (hook) => {
if (hook.type === 'before') {
console.time(`${hook.method}:${service}`)
} else if (hook.type === 'after') {
console.timeEnd(`${hook.method}:${service}`)
}
}
}
this.before({all: h('users/companies/orders/invoices/root')})
this.after({all: h('users/companies/orders/invoices/root')})
}
}
Thank you so much for you help.
Regards,
This happens on the client with feathers-rest and axios:
.find({
query: {
foo: {
$in: foos
}
}
});
With foos = []
this produces an HTTP request with an empty query string, i.e. a plain .find()
and thus it returns all records.
I'd expect it to actually return an emtpy array.
As a workaround i use which returns the expected result (none) for an empty foos
array.
.find({
query: {
foo: {
$in: [...foos, '__dummy']
}
}
});
Status codes from the API need to be handled and errors thrown appropriately as fetch doesn't check error codes internally.
I'm not sure if this is something that is in the scope of feathers-rest
, but basically it would be great if we could intercept requests before they hit the Service e.g. something like middleware for those services. Or perhaps document a standard interface for Service's to follow, so that we can provide a custom subclassed service to use instead of one of fetch
or superagent
etc.
My use case is deduping fetch
requests - basically I might have a bunch of requests going off for the exact same resource i.e. same URL, headers etc. and as a simple way of ensuring they don't double up, subsequent requests made piggy back onto the request that's already gone out.
I've done this already by just wrapping up the native fetch
function and caching requests that are already out - but would love there to be a standard pattern to do this.
I post it here since exactly the same code works fine with feathers-socketio
.
So when I use the $in
operator and provide an array of values for a field, the result query consists of an object, not an array. For example, the following query
.find({
query: {
subfile: state.subfile._id,
number: {
$in: [0, 1, 2]
}
}
})
results in the following hook.params.query
value:
{
number: {
$in: { 0: '0', 1: '1', 2: '2' }
}
...
}
or see the debug console output:
This obviously doesn't pass as a correct query (in my case for Mongoose). As I mentioned, I see no such problem using socketio.
Right now you support as external transport jquery, request, superagent, fetch.
Is there any plan to add angular2 http client support?
It breaks all the time (latest see #24) and doesn't work with many Node versions. We should make a browser test for jQuery and run it in Phantom instead.
An example code:
app.service('/messages').create({
text: 'Hello'
}).then(result => {
...
}).catch(error => {
return error.response.json() // Never resolves
}).then(response => {
// Never gets here
...
})
This is using node-fetch
or the built-in React Native fetch
.
hi,
apologies in advance for potentially being dense, but i can't seem to locate the syntax for something like a $gte
query in a rest-ful url, the following:
/people?$gte[age]=21
incurs something like:
Error: Invalid value [object Object]\n at...
any guidance appreciated!
thanks,
tony.
Call a service method which returns a 204
status with no body while using the fetch
connection - response.json()
then fails to parse the body and throws and error.
https://jsbin.com/wacosaneqo/edit?html,console
It should return a null
response and throw no error
Throws Error: Unexpected end of JSON input
Operating System:
macOS Sierra
Browser Version:
Chrome 54
Same code was working fine before I updated some lib modules to their later versions. I believe, those libs were totally irrelevant to the code below. I am not sure whether this error belongs here or in some other module, but I am logging it here with below error logs pointing in feathers:rest module:
feathers:rest REST handler calling
find
from/auth/instagram
+19s
feathers:rest REST handler callingget
from/auth/instagram/callback?code=acc66d95cd0f4bd49888f5153beb61a2&state=true
+987ms
feathers-authentication:oauth2 Updating user: 575516a41764b5b4cd1fdd85 +2s
feathers:rest Error in REST handler:Invalid atomic update value for $__original_remove. Expected an object, received function
+5ms
feathers-authentication:middleware An authentication error occurred. +6ms Error: Invalid atomic update value for $__original_remove. Expected an object, received function
at Query._castUpdate (D:\Dev\workspace\WebstormProjects\ES6\angular2-esnext-starter\node_modules\mongoose\lib\query.js:2323:13)
at Query.update (D:\Dev\workspace\WebstormProjects\ES6\angular2-esnext-starter\node_modules\mongoose\lib\query.js:2106:22)
at Function.update (D:\Dev\workspace\WebstormProjects\ES6\angular2-esnext-starter\node_modules\mongoose\lib\model.js:2054:13)
at Object.patch (D:\Dev\workspace\WebstormProjects\ES6\angular2-esnext-starter\node_modules\feathers-mongoose\lib\service.js:247:27)
at D:\Dev\workspace\WebstormProjects\ES6\angular2-esnext-starter\node_modules\feathers-hooks\lib\hooks.js:74:31
at new Promise (D:\Dev\workspace\WebstormProjects\ES6\angular2-esnext-starter\node_modules\core-js\modules\es6.promise.js:193:7)
at D:\Dev\workspace\WebstormProjects\ES6\angular2-esnext-starter\node_modules\feathers-hooks\lib\hooks.js:58:16
at run (D:\Dev\workspace\WebstormProjects\ES6\angular2-esnext-starter\node_modules\core-js\modules\es6.promise.js:89:22)
at D:\Dev\workspace\WebstormProjects\ES6\angular2-esnext-starter\node_modules\core-js\modules\es6.promise.js:102:28
at flush (D:\Dev\workspace\WebstormProjects\ES6\angular2-esnext-starter\node_modules\core-js\modules_microtask.js:18:9)
at _combinedTickCallback (internal/process/next_tick.js:67:7)
Please guide me where I should look for answers.
Thanks.
Hi, is it possible to get 'distinct' records through a rest call (e.g. With the mongoose distinct())? Is possible to Perhaps add it via a before hook?
E.g. If I have a collection full of books, and I want to get just the names of all distinct Authors
While testing auth I have noticed that feathers-rest returns Error: Internal Server Error
on invalid login while both socket transports return {name: "NotAuthenticated", message: "Invalid login.", code: 401, className: "not-authenticated", errors: Object}
. Here is a gist with an example: https://gist.github.com/juodumas/ef831aa1f595e7745d7e418108bea461
I get the following error when using fetch in the browser (polyfilled, but using native window.fetch) when the call returns a http 400:
body.on is not a function
over here: https://github.com/feathersjs/feathers-rest/blob/master/src/client/fetch.js#L31
Shouldn't response.json()
be used to parse the body even in the case of an error?
Body has no on
method.
I am trying trying to update a document using put and it is returning 204 instead of 404 , when id in the url is wrong.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.