Improvements to Talawa #1997
Replies: 23 comments 91 replies
-
Discussion reference - here |
Beta Was this translation helpful? Give feedback.
-
AuthorizationSince we're revamping the structure and upgrading the Authorization: Sample: const PermissionSchema = new Schema({
canView: { type: Boolean, default: false },
canEdit: { type: Boolean, default: false },
// Add more permissions as necessary
});
const RoleSchema = new Schema({
name: String,
color: String,
permissions: PermissionSchema
});
const OrganizationRoleSchema = new Schema({
isApproved: Boolean,
isBlocked: Boolean,
organization: { type: Schema.Types.ObjectId, ref: 'Organization' },
role: { type: Schema.Types.ObjectId, ref: 'Role' }
});
const UserSchema = new Schema({
username: String,
email: String,
organizations: [OrganizationRoleSchema]
}); So, for every feature on the platform, we'll check if they have the permission to access it. Just bcuz we are implementing Casl, along with it we can have custom/default roles too. We can use those roles along with API calls to check the access using casl. Example: const techInc = await Organization.create({ name: 'Tech Inc.' });
const marketingCo = await Organization.create({ name: 'Marketing Co.' }); Roles: const adminRole = await Role.create({
name: 'Admin',
permissions: { canView: true, canEdit: true }
});
const memberRole = await Role.create({
name: 'Member',
permissions: { canView: true, canEdit: false } // maybe createEvents, attendEvents
}); Users: const user1 = await User.create({
username: 'user1',
email: '[[email protected]](mailto:[email protected])',
organizations: [
{ organization: techInc._id, role: adminRole._id },
{ organization: marketingCo._id, role: memberRole._id }
]
}); |
Beta Was this translation helpful? Give feedback.
-
Fastify and graphql-yoga are already discussed. For authentication lucia auth should be used, passport.js seems abandoned. Some considerations:-
Again since talawa api is a monolith, for authorization something like casl could work just fine. One issue is that authorization isn't simply about roles and attributes, it's also about relationships and inheritance(direct or indirect) which oso is really good modeling at(but overkill for talawa api). In those cases more data from the database would be required to make authorization decisions. Once again, this would need smart caching and eviction strategies so that authorization data that is accessed frequently doesn't have to be fetched from database each time the same decision has to be made. Mutations to entities would have to handle corresponding cached authorization data. The final crutch is mongoose and mongodb and mongoose, the latter in particular. Mongodb has no strict schema and a bad relational model. It leads to contributers making horrendous database designs without much thought put into it which just leads to technical debt. Anyway I don't want to go on a rant here so I'll stop. Mongodb can be made less painful with a proper ORM on top of it. One thing to realize is that using an ORM makes any database less performant, and since mongodb is already so slow at resolving data across many collections there are noticeable runtime costs, something to be aware of. Coming to mongoose, I don't think the codebase can be seamlessly type safe and error free with it. I recently noticed that it doesn't even complain if we try to populate(similar to joins in SQL) an invalid field that doesn't exist in the mongoose schema. This error can't be caught by typescript and it lets bad code enter the codebase without proper inspection. Typescript is a tool developed to ease the work of catching bugs at compile time, using non type safe tools like mongoose is anti typescript. It returns the |
Beta Was this translation helpful? Give feedback.
-
From @DMills27
|
Beta Was this translation helpful? Give feedback.
-
We are going too fast making assumptions with |
Beta Was this translation helpful? Give feedback.
-
We have tried using cloud services in the past for various services and it is too much of a headache for our developers, end users and the Foundation.
|
Beta Was this translation helpful? Give feedback.
-
@DMills27 This was the rationale for selecting |
Beta Was this translation helpful? Give feedback.
-
Unpopular opinion, why are we even using Express JS ?, For everything we need to install a package which becomes deprecated after sometime and then again we search for a newer package and the cycle goes on and on. What if we use Django ?
Also by default it supports SQLite database, so no need to setup MongoDB, also if we really want to use MongoDB, it can do that as well. SQLite3 is a file system based database, so no need to host it somewhere separately on cloud.
While Django supports every use case of ours, there are some important considerations also,
TLDR; If we really want to change our backend framework, we can think of Django, despite the initial efforts, it will really be fruitful in the longer run. |
Beta Was this translation helpful? Give feedback.
-
I know there is concern about the framework. Is there agreement on this?
|
Beta Was this translation helpful? Give feedback.
-
@DMills27 Thanks for your careful consideration of the potential challenges associated with migrating to Fastify. I acknowledge for this considerations But our migration goal is not just to save milliseconds about response and latency but to enhance the overall efficiency and maintainability of our codebase in the long run. The migration decision is being approached with a focus on the long-term value and benefits that Fastify can bring to the Talawa API and to get rid of the third-party packages utilized to support the express. Here's why Fastify over Express:
Why Fastify? Fastify is a modern alternative to Express. It shares a similar syntax with Express, so most of our Express knowledge will still apply to Fastify. With Support to TypeScript Community Faster Performance Fastify was designed to be fast from the ground up and use fewer system resources, so it handles more requests per second compared to Express. In the future when we go to auth requests etc.. It will show an impact on performance and scalability Although Express is a more mature framework with a larger community and a more comprehensive ecosystem of third-party packages, we are trying to eliminate dependency on this packages in our codebase for better maintainability. Plugin Architecture Fastify also provides a powerful plugin system that can easily add custom functionality. Many official plugins handle things like authentication, validation, security, database connections, rate-limiting, etc. There's also a growing ecosystem of third-party plugins that can be integrated and we can easily create our own plugins. Express is extensible through middleware functions injected into the request/response processing pipeline to modify its behavior. Still, they are tightly coupled into the framework and less flexible or modular than Fastify's approach. Plugins in Fastify are also encapsulated by default, so we don't experience issues caused by cross-dependencies. Security:
Its plugin system also makes it easy to apply additional security measures to our Talawa. On the other hand, Express relies more heavily on middleware to handle security concerns. It does not have built-in validation or schema-based request handling, although several third-party packages can be utilized for this purpose making more fluffy the codebase Built-in JSON Schema Validation In Fastify, JSON schema validation is a built-in feature that allows to validate the payload of incoming requests before the handler function is executed. This ensures that incoming data is in the expected format. In contrast, Express does not provide built-in support for JSON schema validation and relies on third party packages this requires additional setup and configuration. A Built-in Logger Fastify provides a built-in logging mechanism based on Pino that allows to capture various events in API. Once enabled, Fastify logs all incoming requests to the server and errors that occur while processing requests. It also provides a convenient way to log custom messages through the log() method on the Fastify instance or the request object. As we can see, Fastify offers numerous advantages over Express, making it a compelling option for modern web applications. I doesn't oppose the Express but why can't we grasp this features of Fastify into our Talawa and make improvements to go for modern frameworks of worth exploring and go for industry opinions Note I agree with your emphasis on fastify has a steeper learning curve due to its plugin architecture and support for async/await. However, once we get familiar with Fastify's API, it can be just as easy to use as Express and documenting them can be easily understandable by our contributors who has an understanding in what express do. @palisadoes @xoldyckk @DMills27 @rishav-jha-mech @SiddheshKukade @EshaanAgg @noman2002 |
Beta Was this translation helpful? Give feedback.
-
@DMills27 Here's the results of benchmark and the stress tests to compare Express server and Fastify server. I used benchmarking tool Autocannon to this. I used two approaches to compare. One with simple test to fetch requests : Hello World Scenario: Fastify Results: Express Results: Let’s look at the average requests that Fastify has succeeded to serve it, It succeeded to serve about on average, 50,000 requests, which is a lot and I think, the speed is about two and a half times faster than what we had with Express. Another Test with MongoDB Fastify Results: Express Results: By comparison, Fastify delivered the 99th percentile in two milliseconds with an average of approximately 8800 requests per second and it served about 86K results. Fastify claims that they’re the fastest framework around. I can say that currently, they’re right. |
Beta Was this translation helpful? Give feedback.
-
@palisadoes As @rishav-jha-mech mentioned are there any plans to using of PostgreSQL? |
Beta Was this translation helpful? Give feedback.
-
Though there may be faster packages than those we use now, most Talawa users will be small non-profits doing only a few dozen interactive transactions per minute for administration and a few hundred per minute across the API instance. Saving a few milliseconds per transaction that could be unnoticeable at the risk of adopting a risky framework needs to be considered. |
Beta Was this translation helpful? Give feedback.
-
The greater immediate risk looks like the inconsistent auth. That is where our efforts should be focused. A robust set of packages used or backed by Fortune 500 or Global 1000 type tech companies provides much greater comfort. We need to select something that should only require point release upgrades in future versus a forklift replacement. We are a volunteer community with limited human capital to do the work. |
Beta Was this translation helpful? Give feedback.
-
As I earlier mentioned, our migration goal is not just to save milliseconds about response and latency but to enhance the overall efficiency and maintainability of our codebase in the long run. The migration decision is being approached with a focus on the long-term value and benefits that Fastify can bring to the Talawa API and to get rid of the third-party packages utilized to support the express that packages may be deprecated or abandon and can safely eliminate them in our codebase. We can use fruitful plugins support of fastify instead, that has LTS for Typescript Community |
Beta Was this translation helpful? Give feedback.
-
Please don't make so many pointless threads for discussion, try keeping it to as few threads as possible so it's easier to track the conversations. Nobody's choosing fastify for its advertised speed(which is a real thing and not a hoax), it is just an added benefit. Here's the most reputed benchmarks for frameworks across programming languages if someone still wants to check. Express doesn't work well with promises(async/await) which is the standard for concurrency in javascript. This is because it was written in an era when promises weren't standardized. It is based on callbacks instead of promises. Fastify has first class support for both promises and callbacks. Express doesn't work well with esmodules which is the standard for modularising javascript code(splitting code between files). Esmodules are supported both on browsers and servers which makes the javascript code isomorphic and reusable across environments. Technically this isn't beneficiary because talawa api is seperated from any frontend code but still it needs to be done because all modern javascript tooling is written in esmodules syntax. Express Isn't backed by any corporations or sponsors. It doesn't have active maintainers. Express.js v5 has been in a sad state since its proposal back in 2015. Fastify is backed by corporations and sponsors. It is actively maintained by people well known in the javascript ecosystem. DefinitelyTyped is a github repository which hoards types for js packages that don't provide typescript support by themselves, all I haven't provided sources for all these because most people active in the javascript ecosystem already know all this. Most javascript ecosystem has moved off to serverless platforms so backend javascript frameworks aren't as prevalent anymore. But since the requirement here is a good backend javascript framework, fastify and nest.js are the only mature alternatives. Nest.js under the hood itself uses express.js and fastify and provides option to use one or the other, it's only there to bring order to the codebase using class based components, which imo are just a fad. So, basically fastify is the only mature solution for developing a monolithic backend service in javascript while also being customizable. @DMills27 talked about the big amount of disruption this would cause in the codebase. This is completely false. Most of the codebase is abstracted behind graphql which has nothing to do with what web framework is being used. Same goes for the the graphql engine as the graphql code is written in a way that makes it compatible with any graphql engine. Both the http framework and the graphql engine can be swapped out with alternatives quite easily. Idk what he meant by async/await being complex as that is the standard way to do concurrent tasks in javascript, it is not additional complexity, it is already present in the codebase. If fastify's plugin architecture is a problem then other frameworks like hono should be considered. Yes that is why I don't think third party providers for authentication make sense here. Mongodb is already a third party database provider here. The goal is to have as less third party providers as possible, so that the amount of extra costs someone hosting talawa api has to pay is lower. These companies either have their own solutions for this that they've built from scratch or they use some authentication as a service provider. A production level authentication system providing solution for all possible use cases while being easily to integrate in the business logic is not something that can be provided as a library. For this use case authentication has to be decoupled and ran as a seperate service. Yes, I do think lucia is the best option in javascript ecosystem right now to have a good authentication system that could be easily integrated in the codebase. It supports sign in using email/password, oauth openid connect(single sign on) and has plans to support webauthn(passkeys) in the future. Casl is a decent choice and the only choice for a authorization library in javascript ecosystem as far I'm aware. Oso's polar language is one of the best ways for modeling authorization decisions that I've seen. But oso's open source library has been deprecated and right now it only offers a cloud based solution for authorization which is something that is to be avoided since the point is to have as less dependency on external cloud providers as possible. Postgresql is the most advanced and most popular SQL database in the world and is completely open source. Most innovations in the SQL database space are first introduced in postgresql. It is backed by big coporations and used widely in the industry. You can check the stackoverflow developer survey. For mongodb either prisma or microorm should be used. If the database implementation is to be migrated to postgresql drizzle orm should be used. |
Beta Was this translation helpful? Give feedback.
-
As a hosted solution, it will require every Talawa organization to apply for the reduced fees. Most cloud organizations require you to submit scans of your articles of incorporation and governmental approvals for you to get free services. In some cases, you have to renew annually, though with less documentation. Third party services supporting Talawa end user operations have proven to be historically unsuitable for our needs. |
Beta Was this translation helpful? Give feedback.
-
@AVtheking, though it's an interesting technical challenge, we should not be trying to reinvent the wheel with the limited volunteer resources we have. Auth* has been fixed by the coder community, we just need to select from the most robustly supported reputable options. |
Beta Was this translation helpful? Give feedback.
-
I cannot speak with authority on the technical aspects of the various packages. Using Regarding RDBMS options, yes they are more suitable for the relational aspects of the app, however Mongo has its advantages too. MySQL, MariaDB and Postgress all seem to have NoSQL features now which may or may not be suitable for our needs. There could be ways to use Mongo for some things and the historically tested RDBMS (MySQL etc.) options for others. Once again, this would require deeper analysis. This change would also need to be as transparent as possible to the Mobile and Admin clients. It may be a lot of work and could possibly be suitable for one or more of our GSoC ideas. If it's not a lot of work, then we can think about doing it in the coming weeks. Whatever the solution, we need a scope that will be achievable in the proposed time frame. The two obvious options are within the next month, and over the summer. |
Beta Was this translation helpful? Give feedback.
-
No one has answered this question:
The aim of this discussion is to ensure long term stability and maintainability. I've only read that these packages are good choices without the supporting non-technical rationale. The assertion that they are "industry best practice" without supporting evidence is insufficient justification. |
Beta Was this translation helpful? Give feedback.
-
@palisadoes A thing to discuss about File Uploads, @xoldyckk just suggested here his opinion about using gridFS, most of they stuck with this. It isn't only a solution for it. I have done detailed research on why can't be GridFS and what are alternatives to support our Talawa goals and sent it to [email protected]. Have a look at it :) The rationale for selecting gridFS instead of S3 is due to its costs and cloud provider, IMO there are other alternatives solutions for this usecase |
Beta Was this translation helpful? Give feedback.
-
Is there agreement on this?
@DMills27 @palisadoes @xoldyckk @rishav-jha-mech @SiddheshKukade |
Beta Was this translation helpful? Give feedback.
-
Supabase was mentioned as a possibility for the self hosted chat and notifications GSoC idea. I did some research and discovered that it also handles auth. Supabase is backed by a company |
Beta Was this translation helpful? Give feedback.
-
Current Goals:
Moving our backend framework from express to modern frameworks like fastify or hano adheres to current industry practices and adapting new technologies and tools to our project. Let's go step by step implementing the features you suggested, the above suggestions are really amazing for incorporating the latest technologies into our project.
casl
in Talawa-Api and use thepackRules
andunpackRules
function in@casl/ability/extra
to transfer the necessary rules to Talawa-Admin. We can go with standard authorization logic that also supports security features and is currently the most used in the industry.OSO integration makes a larger learning curve and learning polar and makes difficult in integration.@xoldyckk What's your thoughts on this
Plan of Approach :
Here's a breakdown of the major steps and sequencing for the above tasks :
Fastify Integration:
index.ts
,app.ts
etc... Will require Incremental migration from Express to Fastify to restore functionality as same as the express and to ensure compatibility.References:
https://fastify.dev/docs/latest/Reference/TypeScript/
https://blog.appsignal.com/2023/06/28/migrate-your-express-application-to-fastify.html
GraphQL-Yoga Integration:
References:
https://the-guild.dev/graphql/yoga-server/docs/integrations/integration-with-fastify
While authentication and authorization are logically separate concerns, they often depend on each other. Authentication is a prerequisite for effective authorization. Coordination between the authentication and authorization aspects is crucial.
Authentication
Passport.js is a great choice for our project because it is easy to use and provides a lot of flexibility. It is also well-maintained and has a large community of users. Passport.js supports a variety of authentication strategies, including local username and password authentication, OAuth, and JWTs.
auth.ts
using Passport.js node middleware for standard authentication as we currently using JWTs.Authorization:
packRules
andunpackRules
functions in @casl/ability/extra to transfer the necessary rules to Talawa-Admin. We can go with standard authorization logic that also supports security features and is currently the most used in the industry.@palisadoes @xoldyckk @disha1202 Here's the discussion for our ongoing discussions for improvements for Talawa.
Beta Was this translation helpful? Give feedback.
All reactions