Backend - rishavry/WorksPresentation GitHub Wiki
Below is the list of some of the many backend best-practices which I learned from a year of experience. For any backend-project that comes my way, I am more than prepared to meet all the guidelines below.
-
Each endpoint should use rate-limiting to prevent Denial-of-Service attacks.
-
All sensitive data (i.e credentials/API-keys/etc) should be retrieved with environment-variables instead of hard-coded, so that they are not exposed publicly in version-control systems like Git.
-
CORS should be used to prevent browsers at specific origins from accessing data from the backend. However, CORS doesn't make a difference when it comes to non-browser requests and when it comes to modifying data (i.e POST/PUT/PATCH/DELETE/etc).
-
99% of endpoints should follow this sequence of steps: input-validation, user-authentication(i.e with cookies), fetching the asked-for-data and/or adding data, making any adjustments to related data as a result of the API-request, then returning the response as a dict, with one of the key's being 'Error Message'(with the value being a string that has all the errors that occurred), and another key being whatever is relevant to the API-request.
-
Exception-handling and using appropriate status-codes are key for the client to understand the outcome of their request.
-
GET requests don't support request-bodies, hence if you wish to receive complex data that isn't URL-safe, it's best to set the endpoint as POST or something that isn't GET, even if the whole purpose of the endpoint is the same as that of a GET request.
-
The server should be running on production-mode and HTTPS.
-
Add documentation to unclear code. Be consistent with spacing and indentation for the sake of organization and readability.
-
Models, Services, and Controllers should all be organized in their own directories.
-
Anti-CSRF tokens should be used to prevent Cross-Site Request Forgery attacks, unless the user-auth cookies are same-site only and the backend-server and the frontend-server(s) are all on the same domain.
-
Backends should be able to connect to each other, and to WebSockets to provide them with updates on data.
-
There are several instances where backend-servers should run background-code at intervals of time. For instance, to revert data to its original state after, for example, the backend attempts to change 5 pieces of data but only 3 were able to be changed(i.e due to database-connection-issues, etc). Another example is wherever concurrency of requests can lead to data-conflict/race-conditions, there should be code that runs every 2s(for example) to process the data sequentially.
-
In the process of CI/CD(i.e using Gitlab/Jenkins/etc), there should be must-pass tests for each 'non-simple' endpoint of the backend. These tests should use a bunch of diverse LeetCode-style test-cases, big and small, including edge-cases. To test a GET request endpoint, you can call the endpoint and see if the data accessed matched what was expected. Furthermore, to test a POST/PATCH/PUT/DELETE/etc request, you can call the endpoint and see if the database reflects the expected changes. For some tests, the real database should not be used and instead a mock database (i.e a version of the real-database with mock-data).
-
For SQL-like queries and mutations to data, GraphQL should be used over REST-API.