Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Be able to create custom routes #93

Closed
ekryski opened this issue Sep 1, 2014 · 9 comments
Closed

Be able to create custom routes #93

ekryski opened this issue Sep 1, 2014 · 9 comments
Labels

Comments

@ekryski
Copy link
Contributor

ekryski commented Sep 1, 2014

I would like to be able to specify what mime types are supported via rest:

app.use('/users', UserService, {
  json: true
});

// which might result in /users.json and /users/1.json being the routes

and also create namespaced routes:

app.use('/users', UserService, {
  json: true,
  prefix: 'api'
});

// which might result in /api/users.json and /api/users/1.json being the routes

Similar idea to #86 but I don't think using the .setup() method is elegant or efficient.

@ekryski ekryski added the feature label Sep 1, 2014
@daffl
Copy link
Member

daffl commented Sep 2, 2014

I'm not sure the prefix is necessary. Why couldn't you just do

app.use('/api/users', UserService);

Or create a separate app and use it on a different route (as done with the new Testee):

var api = feathers().use('/users', UserService);

// Map that app to /api (will provide /api/users)
var app = feathers().use('/api', api);

As for the content type, Express does allow REST content negotiation, for Feathers like:

app.configure(feathers.rest(function restFormatter(req, res) {
  res.format({
    'text/plain': function() {
      res.end('The todo is: ' + res.data.description);
    },
    'application/json': function() {
      res.json(res.data);
    }
  });
}));

I don't think you can use file name extensions this way but setting the Accept HTTP header should be possible with every client.

@ekryski
Copy link
Contributor Author

ekryski commented Sep 2, 2014

Or create a separate app and use it on a different route (as done with the new Testee):

Very clever Dave 😉. Totally didn't think of that one.

As for content negotiation say I want to render out a specific template. For example I hit the /users endpoint and I want to render out the 'users' template for html. When I tried that I actually didn't have access to the request object and therefore wasn't able to determine the path.

@daffl
Copy link
Member

daffl commented Sep 2, 2014

I would keep that separate from the service though. In the negotiator it would be

app.configure(feathers.rest(function restFormatter(req, res) {
  res.format({
    'text/html': function() {
      var template = req.url;
      res.render('/views/' + template, res.data);
    },

    'application/json': function() {
      res.json(res.data);
    }
  });
}));

The view information could also be added with a custom middleware:

app.use('/users', function(req, res, next) {
  req.view = 'views/user.jade';
  next();
}, UserService);

@ekryski
Copy link
Contributor Author

ekryski commented Sep 2, 2014

Yep that works pretty well and what I had tried. For some reason my req.path is not right so I need to grab req.route.path.

Regardless, the solution is good but it gets complicated when you have urls like /users/:id and you want to res.render('user', {data: res.data}). Possibly namespacing your feathers routes and declaring your own html route handlers might be the best solution for separating JSON/XML routes from HTML ones.

Otherwise you end up writing some janky logic to determine which template should be rendered based on the route path. This could get really complicated if you have stuff like /users/:id/subscriptions, as an example.

@agonbina
Copy link

agonbina commented Oct 9, 2014

@daffl In the case where you have

var api = feathers().use('/users', UserService);
var app = feathers().use('/api', api);

do configurations from app apply to the api instance too?
Ex. if I have

app.configure(feathers.rest())
.use(bodyParser.json())
.use(...other feather instances ...)

, do we still need to do the same for api or since we have applied those configs before 'mounting' api they would apply to it as well?

Thanks!

@daffl
Copy link
Member

daffl commented Oct 9, 2014

I don't think so. Every Express application has its individual middleware stack. The easiest way is probably to put common middleware into a separate setup function and .configure it on each application:

function setup() {
  var app = this;

  app.configure(feathers.rest())
    .use(bodyParser.json())
}

app.configure(setup);
api.configure(setup);

@agonbina
Copy link

agonbina commented Oct 9, 2014

Yep, just tried leaving out configuration for the api and it no longer works as expected, so definitely each instance has its own middleware stack.

Thanks for the quick response!

@daffl
Copy link
Member

daffl commented Dec 16, 2014

I think we can close this issue? If there is still things to think about I'd put them in a new one. I worked with a Feathers app that had some static pages and didn't run into any hard problems connecting services and rendering static pages.

@daffl daffl closed this as completed Dec 16, 2014
daffl added a commit that referenced this issue Aug 21, 2018
* Update to new plugin infrastructure and npm scope (#92)

* Update to new plugin infrastructure and npm scope

* Update debug dependency

* Update year and release script

* Prepare prerelease

* 3.0.0-pre.1

* Updating changelog
daffl added a commit that referenced this issue Aug 21, 2018
* Update to new plugin infrastructure and npm scope (#92)

* Update to new plugin infrastructure and npm scope

* Update debug dependency

* Update year and release script

* Prepare prerelease

* 3.0.0-pre.1

* Updating changelog
@lock
Copy link

lock bot commented Feb 8, 2019

This issue has been automatically locked since there has not been any recent activity after it was closed. Please open a new issue with a link to this issue for related bugs.

@lock lock bot locked as resolved and limited conversation to collaborators Feb 8, 2019
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Projects
None yet
Development

No branches or pull requests

3 participants