Polling Webs App - Routers, Controllers & Updating Polls
As I have continued to develop the polling app parts of it have grown and will continue to grove unless I get ahead of it. Currently I only have a few routes, however it has become apparent that I have to separate the router and controller from "app.ts". While it might seem like optimizing a bit too early, doing so now, while the app's functionality is fairly simple, makes it more manageable. Along with separating the router and controller, I also added functionality to allow polls to be updated. This is the first time a feature was made entirely with the new separation.
Polling Router and Controller
Separating the routes into a Router
Starting off by separating the routes from "app.ts", first make a new directory in the "src" directory called router that will host all of the router files. Within the new directory add a file named "polls.routes.ts" this file will host the routes related to polls. From "app.ts" copy the existing poll routes and paste them into the newly created file. Import the "Router" module from Express and make an export const that use the "Router" module name "pollRouter". Lastly change two things about the existing routes, change it so they use "pollRouter" instead of "app" and the create names so they are "create", "get-all" and "get-by-id".
Creating a Controller for the Router
For the next part, is to separate out the controller from the router. Similar to what was done with the router, make a new directory in the "src" called "controller". Make a new file called "polls.controller.ts" where the controller of polls will live. In the newly created file import "Request" and "Response" from "Express". Additionally import the services from "addPolls.ts" and "getPolls.ts". Create three export functions, they are named the following "addPollController", "getAllPollsController" and "getPollsByIdController". From each route copy the portion of the route that handles what the route actually doesinto the appropriate function.
Setting Up the Router for the Server
With the router and controller being separated, the functions "addPollController", "getAllPollsController" and "getPollsByIdController" need to be imported into "polls.controller.ts". Replace the existing router logic and the correct controller so that the route uses that controller. Moving from the poll router to "app.ts" remove any routes in the file. Import the router into app.ts and make a new endpoint that uses the poll router with a route prefix of "/polls".
Updating Polls
Making the updatePoll Service
Moving on from the separation of the router and controller from "app.ts", to updating a poll, more specifically its question/query. In the "services/polls" directory a new file was added named "updatePolls.ts". In this file these were imported into it, "eq" from "drizzle-orm", "db" from "drizzle.ts", and "polls" from "schema.ts". An exported function, "updatePollById", was created to handle poll updates. This function takes two arguments: "pollID" of type "any" and "updatedQuestion" of type "string". The function queries the database to locate a poll with a matching provided ID then update the question field to the provided string.
Making the updatePoll Controller
A new controller for the "updatePollById" needs to be created. Start by importing the "updatePollById" service into the polls controller. Make a new export function called "updatePollByIdController" that uses a try-catch block. Within the try block, destructure the "pollID" and "updatedQuestion" from the request body, validate the presence of both, and call the "updatePollId" function to perform the database update. Once the database update is completed is send a success response, while the catch block handles the any errors.
Making the updatePoll Route
For the server to handle polls update a new route has to be made, the route's prefix will be "/update-by-id" and the HTTP method will be a PATCH. Import the "updatePollByIdController" into "polls.router.ts" and have the newly created route use the imported function.
Conclusion
By separating out the router and controller from "app.ts" early, I make structure of the project easier to work with as I continue from this point onward. It might be a little premature to this, but by addressing this now I don't have to worry about having to handle such a larger overhaul to achieve the same end goal.
Trying out the new structure of the app with an additional feature was a great test of how well it can be done, while at the same time expanding what the app is capable of. There is still more to be done for the backend at the moment, but the app continues to take shape with each new feature.
If you would like to check out the code or us it for yourself: Github Link
If this blog was helpful to you please consider subscribing.