Build a REST API in Deno using MongoDB and Oak
Deno is the new buzzword since its release and we are all over it.
RESTful API’s have been around for a while, as a developer it’s almost an unwritten rule to learn how to make a REST API when dealing with a new technology. It makes you understand the basics of that technology and makes it easier to dive deep in that technology. As per Wikipedia — ‘RESTful Web services allow the requesting systems to access and manipulate textual representations of Web resources by using a uniform and predefined set of stateless operations’.
In the preceding article we built a basic Deno server and used its weather API to get location specific weather updates in JSON format.
Prerequisites: Make sure you following requirements are met on your system
- Deno must be installed on your system.
- MongoDB must be installed to handle our database or an online hosted MongoDB will also be fine.
- A internet connection is needed for importing functions from deno at runtime.
- If you use VS Code make sure you add supporting extension for Deno.
- Make sure you have Postman installed on your system. Or else get it at Postman.com
PART 1: Build Deno RESTful API
Now let’s start building our REST API 👨🏻💻
1. Create a folder name ‘deno-mongo-rest-api’ and create the following folder and file structure
We are a implementing CRUD (Create, Read, Update, Delete) application for a Pizza Shop 🍕
│ └── pizzas.ts
│ └── mongo.ts
2. Create a server in app.ts file
The Application wraps the serve() fro http package.
We will add our routes in the two methods
router.routes()— It allows all the routes defined in the
routes.tsfile through the router object.
router.allowedMethods()— It allows all the methods used in Oak routing such as
GET, POST, PUT, DELETE.
3. Create a routes in /routes/router.ts file
We will use /api/v1/ as a version 1 for our API it is the best practice so that we can manage versions in the near future.
router.get(“/”, home)— We use
“/”for our home page and return a hello message and routes information. It is always better to return something on the homepage not returning a message makes a bad impression.
router.get(“/api/v1/pizzas”, getPizzas)— In this route we simply fetch the pizzas from our database and return the json object to the client.
router.get(“/api/v1/pizzas/:id”, getPizza)— In this route we fetch only one pizza from the database and return it to the client.
router.post(“/api/v1/pizzas”, addPizza)— Here we use post method to add a new pizza to the database and return message of success to the client.
router.put(“/api/v1/pizzas/:id”, updatePizza)— In this put route update a pizza in the database.
router.delete(“/api/v1/pizzas/:id”, deletePizza)— In this delete route we delete a single pizza from the database.
We import handler functions from
/controller/pizzas.tsthis is also considered as one of the best practices. We will build the handlers in the 4th step after we design our database handler function in MongoDB.
4. Configure our MongoDB in /db/mongo.ts
MongoClient is the deno_mongo module we import to access MongoDB functions.
After instantiating the MongoClient function, we connect to the MongoDB database using
URIis the MongoDB URI that we pass to the
connectWithUri()to connect our database. I am using MongoDB on my local machine hence the URI is from the local Mongo URI.
The db variable is an instance of database named
“test”, similarly the
pizzaObj is the instance of collection in test database named
And finally we export the
pizzaObj so we can import it in our handler to carry out CRUD functions.
5. Implement handlers in
The following code we are about to write in
pizzas.tsis a long one, so I recommend reading a single function explanation and then go to the referred line number in the code.
To understand the concepts perfectly, implement a single handler function and test it for only that route, this will reduce any possible errors. For testing instructions below in this article.
We just created our
pizzasObj in the mongo.ts file. Lets import that first so we can define CRUD functions.
home— (refer line 3) its the homepage handler function which only one sends a response.body in which we greet our user and display information about our routes.
getPizzas— (refer line 11) this function returns all the pizzas in the database. It uses the
pizzaObj.find()to get all the pizzas in the database.
getPizza— (refer line 23) as the name suggests this function returns a singular pizza object from the database. It requests an id from the url which is passed as params. It uses
pizzaObj.findOne()which finds the single object in the database. In case there is no object for given id we return a success: false flag and a “no product found” message to the user.
addPizza— (refer line 42) in this function we add a new product into the database. It makes a request with
request.body. Here we give a JSON obj though Postman and make a POST request to the route. We use
pizzaObj.insertOne()to add the data to the database. If the body does not have any data provided then we return a success: false and message “No data provided” to the user.
updatePizza— (refer line 67) We use this function to update an existing pizza object in the database. It takes a
params.idfrom the url and makes a body request to get data from body that needs to be updated the database for the given object id. If the value of the pizza is updated successfuly in the database we return a success: true flag and a message “Updated pizza”. If the pizza is not updated we return success: false and a message “No product found for the given id”.
deletePizza— (refer lie 97) this function is used to delete a single pizza from the database. It only needs the
params.idof the referred pizza obj in the database. Then it passes this id to
pizzaObj.deleteOne()which deletes the pizza object referred by given id parameter and returns success: true and a message: “Pizza deleted”. If the pizza is not deleted from database we return success: false and a message “No product found for the given id”.
6. Run the deno run command in the terminal.
Since we are using MongoDB for database and Oak for middleware functions we need to pass some extra parameters in
deno run command. This is because Deno is secure by default; no file, network, environment access is granted unless explicitly specified.
Run the following command in the terminal to start your Deno server.
deno run --allow-net --allow-write --allow-read --allow-plugin --unstable app.ts
After running the command in step six your terminal should throw this message.
Now the API is complete and being served on our local machine🎉
PART 2: TESTING OUR API
Testing Our API Using Postman
- The drop-down contains all the method to send a request to a particular route.
- The send button is used to send a request to a route with the selected method.
3. While sending JSON data to a route select Body in Postman and follow the setup according to the following screenshot.
Testing Our API
Note: In the testing screenshots given below; the orange color signifies needed environment setup to send a particular request, black is for response received and red is for JSON data we send in the body.
- Testing our Homepage at
GET at route
‘/api/v1/pizzas’ it should return following results.
GET at route
‘/api/v1/pizzas/id’ it should return following results.
Here we pass and id of an object in database, we copy it from the response in above
POST at route
‘/api/v1/pizzas’ with the given JSON in body
We have given pizza and price in the body, as necessary.
PUT at route
Here and id is need to select the database object to be updated and the data to be updated through body as required.
DELETE at route
We delete an object in database using this method, the only parameter passed is the
idin the url.
That’s it! You now have an api in Deno and MongoDB!
Now that we have built and tested a RESTful API in Deno, MongoDB and Oak, we have learned how a REST API actually works in Deno with MongoDB and it’s significance in back-end web development.
This was a simple CRUD app we made, it is a stepping stone towards more complex applications. You can now build your own solutions and handle request and response.
If you have suggestions please let me know in the comments section🙋♂️
Here is the GitHub Repository for all the source code.