I am in the process of mapping an existing API (ebay REST API) to a feathers service and am trying to reason the best way to design the service. The API has multiple endpoints, each with their own GET, POST, etc:
/ebay/inventory/item
/ebay/inventory/location
/ebay/inventory/offer
/ebay/account/paymentPolicy
/ebay/account/returnPolicy
/ebay/account/fulfillmentPolicy
etc...
I would like to avoid having to create a service for each endpoint and wanted to know if its possible to have a single service, with CRUD for each endpoint. Something like below, each subdirectory would have get(), create(), etc for their corresponding endpoint:
services
ebay
inventory
item
location
...
account
...
The feathers scaffolding creates the following, so it seems like all I would need to do is add additional app.use('/ebay/inventory/xxx'). to the base ebay service. Does this look like a good way to go about this? If so, how does one add multiple endpoints to a single service?
...
module.exports = function(){
const app = this;
// Initialize our service with any options it requires
app.use('/ebay/inventory', new Service());
// Get our initialize service to that we can bind hooks
const ebayService = app.service('/ebay/inventory');
...
module.exports.Service = Service
Related
I would like to serve a Next.js app in europe using Firebase Hosting & Functions capabilities.
I do understand from the doc that:
If you are using HTTP functions to serve dynamic content for Firebase
Hosting, you must use us-central1
and that
Firebase Hosting supports Cloud Functions in us-central1 only
It's pretty clear: you must use us-central. But my main target is Europe..
I've read the following on the Cloud Functions locations guide:
For HTTP and callable functions, we recommend that you first set your
function to the destination region, or closest to where most expected
customers are located, and then alter your original function to
redirect its HTTP request to the new function (they can have the same
name). [Solution 1] If clients of your HTTP function support
redirects, you can simply change your original function to return an
HTTP redirect status (301) along with the URL of your new function.
[Solution 2] If your clients do not handle redirects well, you can
proxy the request from the original function to the new function by
initiating a new request from the original function to the new
function. The final step is to ensure that all clients are calling the
new function.
I've highlighted what seems to be two solutions to my initial problem:
Solution 1
Have a us-central1 function that send a 301 redirection to https://europe-west1-[myProject].cloudfunctions.net/[myEuropeanFunction]
Have a europe-west1 function that does the job (in my case, serve the Next.js app)
Happily using Firestore located in europe-west1
This would only work if clients of the HTTP function support redirects. In my case, it's fine: all browsers support redirection.
exports.nextServer = functions
.https
.onRequest((req, res) => {
res.set('location', 'https://europe-west1-<my-project>.cloudfunctions.net/nextServerEurope');
res.status(301).send()
});
exports.nextServerEurope = functions
.region('europe-west1')
.https
.onRequest((req, res) => {
return server.prepare().then(() => nextjsHandle(req, res));
});
The issue with that solution is that the URL changes in the browser to https://europe-west1-.cloudfunctions.net/nextServerEurope :-/
Solution 2
Have a us-central1 function that initiate a new/proxy request to the europe-west1 function
Have the same europe-west1 function that does the job (in my case, serve the Next.js app)
Still happily using Firestore located in europe-west1
By proxy request (as suggested in the guide), it would mean using a lib like axios I suppose. I know there are some libraries to perform proxy request available for node as well.
However, with that solution, the first issue I can think of is the unnecessary delay introcuded by passing by the us endpoint:
client -> us endpoint -> eu endpoint -> do stuff -> us endpoint -> client
Billing wise, I'm wondering what would be the impact..
I know that two services from different regions calling each others can increase the latency and the billing (egress).
With the first solution, there's no egress traffic as it's only a redirection to the european endpoint. But the redirection itself is not a valid solution in my case.
It's unclear for me what would be the additional billing cost with the second solution (beside the latency cost): is the traffic for the proxy request from us to eu going to be expensive?
To wrap-up:
The solution 1 is easy but leads to a non-transparent redirection
The solution 2 seems ok but it requires extra http request which leads to extra-latency (and potentially extra billing)
In the end, both solutions doesn't seem quite okay.
Therefore my question:
How do you serve in Europe dynamic content using Firebase Hosting and Functions?
Firebase Hosting only supports Cloud Functions in Us-Central as you mentioned and as stated in the Firebase Hosting Official Documentation.
I have created a Feature Request in Public Issue Tracker to support other regions when using Firebase Hosting with Cloud Functions. Please note, there is no ETA when this will be implemented.
So as #Doug Stevenson suggest, you can use Firebase Hosting with Cloud Run instead to serve your Dynamic Content.
Just to update. As of August 2022.
Finally, latency issue can be solved easily for now.
Firebase Hosting rewrites to CF3 are able to be done to any CF3
region, not just us-central1.
Reference: Feature Request Ticket
Am new to feathersjs am try to do local auth in feathers while creating the service under users.class.js file where there. i don't know what to implement there so kindly guide me with this
const { Service } = require('feathers-mongoose');
exports.Users = class Users extends Service {
create(Users, email, username, password, role ) {
Users.created_at = new Date();
return super.create(Users, email, username, password, role );
}
update(id, Users, users) {
Users.updated_at = new Date();
return super.update(id, Users, users);
}
};
I’d look at the docs to learn more about services.
In Feathers, when you generate a service through the CLI, it creates three files.
service-name.class.js/.ts contains your service definition. Feathers operates everything in a CRUD fashion. So, you’ll see all the CRUD methods here. You can either define the service yourself, or use CLI to define it for you using an adaptor like Mongoose or Sequelize.
service-name.hooks.js/.ts contains all the hooks associated with this service. Feathers likes to keep your logic simple and clean, opting to do things like validation through reusable hooks instead of modifying the service logic directly. You said you wanted to add authentication to your service. This is where you would do it. In the before:[] hook section, add the authenticate(“jet”) hook your the methods you want to require authentication for.
service-name.service.js/.ts just handles service registration with the framework. Starting out, I wouldn’t mess around with this file much. It just performs some setup so the framework knows your service exists and attaches it to a specific route like /users.
Hope this helps.
Looking a bit through the feathers docs I understood that is based on services and hooks and that services have the events that also help to offer realtime sync between server and client.
As long as things are simple, as in docs I understand, basically having a service generated and then adding/saving/updating using the service methods will triggeer the event.
My scenario is a bit different:
The API endpoint does not return info from a table but complex queries based on multiple tables
I need to have background workers that do operations on the database,probably using Kue (if there's no better way inside feathers), when a worker finishes the job, I need to have a way to trigger the API service so it updates the clients with the new data.
How can I do this in feathers?
Both scenarios can be handled with Feathers like this:
Feathers services do not have to be tied to a table. You can implement a custom service just like you would in any other framework (controller). It is not uncommon to create Dashboard services that aggregates different service calls or uses service.Model to access the ORM you are using directly:
class MyService {
find(params) {
const userModel = this.app.service('users').Model;
const invoiceModel = this.app.service('invoices').Model;
return userModel.doSomething()
.then(data => invoiceModel.doSomethingElse());
}
setup(app, path) {
this.app = app;
}
}
Background workers should also be using the Feathers API (in Node this can be done by either using the application directly via const app = require('./src/app') or connecting transparently through Feathers as the client) so that all connected clients will get updates automatically. Then there should be no need to trigger events manually (which comes with caveats like having to also run your raw data through any hooks that change the data).
I build an api rest by express js simply to post an data in my server .
app.post("/register", function(request, response){
var username = request.body.username;
});
How i can do this with feathersjs ? and how i can call it from my reactjs app ?
Feathers is a drop-in replacement for Express. That means you can replace your const app = express(); with const app = feathers() and everything will work just the same, so what you are showing above you can also do with Feathers.
The real Feathers way to accomplish this however is through services which - with the other important concepts - are described in the basics guide.
There are pre-build services for several databases (which can be customized through hooks) but you can always create your own service. It is important to note that Feathers services - unlike the Express middleware you showed - will be available via HTTP (REST) and websockets (which also gets you real-time events). See here how service methods map to REST endpoints.
Your example in Feathers simply looks like this:
app.use('/register', {
create(data, params) {
// data is the request body e.g.
// data.username
// Always return a promise with the result data
return Promise.resolve(data);
}
});
I have been reading the documentation for last 2 days. I'm new to feathersjs.
First issue: any link related to feathersjs is not accessible. Such as this.
Giving the following error:
This page isn’t working
legacy.docs.feathersjs.com redirected you too many times.
Hence I'm unable to traceback to similar types or any types of previously asked threads.
Second issue: It's a great framework to start with Real-time applications. But not all real time application just require alone DB access, their might be access required to something like Amazon S3, Microsoft Azure etc. In my case it's the same and it's more like problem with setting up routes.
I have executed the following commands:
feathers generate app
feathers generate service (service name: upload, REST, DB: Mongoose)
feathers generate authentication (username and password)
I have the setup with me, ready but how do I add another custom service?
The granularity of the service starts in the following way (Use case only for upload):
Conventional way of doing it >> router.post('/upload', (req, res, next) =>{});
Assume, I'm sending a file using data form, and some extra param like { storage: "s3"} in the req.
Postman --> POST (Only) to /upload ---> Process request (isStorageExistsInRequest?) --> Then perform the actual upload respectively to the specific Storage in Req and log the details in local db as well --> Send Response (Success or Failure)
Another thread on stack overflow where you have answered with this:
app.use('/Category/ExclusiveContents/:categoryId', {
create(data, params) {
// do complex stuff here
params.categoryId // the id of the category
data // -> additional data from the POST request
}
});
The solution can viewed in this way as well, since featherjs supports micro service approach, It would be great to have sub-routes like:
/upload_s3 -- uploads to s3
/upload_azure -- uploads to azure and so on.
/upload -- main route which is exposed to users. User requests, process request, call the respective sub-route. (Authentication and Auth to be included as well)
How to solve these types of problems using existing setup of feathersjs?
1) This is a deployment issue, Netlify is looking into it. The current documentation is not on the legacy domain though, what you are looking for can be found at docs.feathersjs.com/api/databases/querying.html.
2) A custom service can be added by running feathers generate service and choosing the custom service option. The functionality can then be implemented in src/services/<service-name>/<service-name>.class.js according to the service interface. For file uploads, an example on how to customize the parameters for feathers-blob (which is used in the file uploading guide) can be found in this issue.