Deno CRUD REST API
Today, we are going to create a Deno CRUD REST API with simple example. Recently, I covered the tutorial on VDOM (Vue, Deno, Oak, and MongodB) stack application. Deno is the infant secure runtime for JavaScript and TypeScript. Many of the reader asked me to write an article to create rest api using Deno.

Generally, if you are familiar with Node.js then Deno is just like that. Except that it’s improved in many ways, it’s created from bottom to top to be a better implementation of Node.js.
Why I use Deno over Node? ?
Since Deno and Node.js serve the same purpose, it’s possible to compare the two directly.
Node | Deno | |
---|---|---|
Engine | V8 | V8 |
Written in | C++ & JavaScript | Rust & Typescript |
Package managing | package managers: npm | uses URLs |
Importing pacakges | CommonJS syntax | ES Modules |
Security | full access | permissioned access |
TypeScript support | not built in | built in |
Okay, cool!! So How can I install Deno in my system? ?
Install Latest Version
With Shell:
1 |
curl -fsSL https://deno.land/x/install/install.sh | sh |
With PowerShell:
1 |
iwr https://deno.land/x/install/install.ps1 -useb | iex |
For more details check Deno’s official installation guide.
After install check the version of Deno using deno –version

Now you can run deno repl to open the REPL (Read-Execute-Print-Loop) and start typing some JavaScript.

Let’s run some Deno example
The entry point can be .js file, .ts file or even a URL that points to an app entry point and Deno will download, compile and then run it for you:
For example: deno run https://deno.land/std/examples/welcome.ts
Come out from playground and Build an API ?
Just like in our previous example, we’ll use Oak framework and Typescript (you can also use JavaScript if you want to).
First of all, create three files app.ts, router.ts and controller.ts
In the app.ts file, we have to imports the Application from https://deno.land/x/oak/mod.ts and the router from ‘./router.ts‘.
Then set the PORT and HOST
1 2 3 4 5 6 7 8 |
import { Application } from 'https://deno.land/x/oak/mod.ts' import router from './router.ts' const env = Deno.env.toObject() const HOST = env.HOST || '127.0.0.1' const PORT = env.PORT || 7700 const app = new Application() |
After that, add the code of router.ts. In this file, we have to import Router from https://deno.land/x/oak/mod.ts and create the routes.
1 2 3 4 5 6 7 8 9 10 11 |
import { Router }from 'https://deno.land/x/oak/mod.ts' import { getBooks, getBook, addBook, updateBook, deleteBook } from './controller.ts' const router = new Router() router.get('/books', getBooks) .get('/books/:isbn', getBook) .post('/books', addBook) .put('/books/:isbn', updateBook) .delete('/books/:isbn', deleteBook) export default router |
At line number 2 in above code, the functions getBooks, getBook, addBook, updateBook and deleteBook are imported from a local file, it’s just we haven’t created them yet.
Before creating these functions in controller, let me finish our app.ts file firstly.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
import { Application } from 'https://deno.land/x/oak/mod.ts' import router from './router.ts' const env = Deno.env.toObject() const HOST = env.HOST || '127.0.0.1' const PORT = env.PORT || 7700 const app = new Application() app.use(router.routes()) app.use(router.allowedMethods()) console.log(`Listening on port ${PORT} ...`) await app.listen(`${HOST}:${PORT}`) |
Now it’s time to create controller.ts. In this file, lets define an interface for a book IBook, then we declare an initial array of book objects:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
interface IBook { isbn: string; author: string; title: string; } let books: Array<IBook> = [{ isbn: "1", author: "Robin Wieruch", title: "The Road to React", },{ isbn: "2", author: "Kyle Simpson", title: "You Don't Know JS: Scope & Closures", },{ isbn: "3", author: "Andreas A. Antonopoulos", title: "Mastering Bitcoin", }] |
Where is the implemented functions in controller.ts?
Now we’ll implement the functions which we define in our router.ts.
Function | Route | Description |
---|---|---|
getBooks | GET /books | return all the books |
getBooks | GET /books/{isbn} | return a book |
addBook | POST /books | add a book |
updateBook | PUT /books/{isbn} | update a book |
deleteBook | DELETE /books/{isbn} | delete a book |
getBooks: returns all the books on the list.
1 2 3 |
const getBooks = ({ response }: { response: any }) => { response.body = books } |
getBook: returns a single book by its isbn, or error message if not found.
1 2 3 4 5 6 7 8 9 10 |
const getBook = ({ params, response }: { params: { isbn: string }; response: any }) => { const book: IBook | undefined = searchBookByIsbn(params.isbn) if (book) { response.status = 200 response.body = book } else { response.status = 404 response.body = { message: `Book not found.` } } } |
addBook: add a book to the books list.
1 2 3 4 5 6 7 |
const addBook = async ({ request, response }: { request: any; response: any }) => { const body = await request.body() const book: IBook = body.value books.push(book) response.body = { message: 'OK' } response.status = 200 } |

updateBook: updates a book if exists, return error message if not.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
const updateBook = async ({ params, request, response }: { params: { isbn: string }; request: any; response: any }) => { let book: IBook | undefined = searchBookByIsbn(params.isbn) if (book) { const body = await request.body() const updateInfos: { author?: string; title?: string } = body.value book = { ...book, ...updateInfos} books = [...books.filter(book => book.isbn !== params.isbn), book] response.status = 200 response.body = { message: 'OK' } } else { response.status = 404 response.body = { message: `Book not found` } } } |

deleteBook: deletes a book from the books list.
1 2 3 4 5 |
const deleteBook = ({ params, response }: { params: { isbn: string }; response: any }) => { books = books.filter(book => book.isbn !== params.isbn) response.body = { message: 'OK' } response.status = 200 } |

Here we finish our controller.ts. Full code would be:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 |
interface IBook { isbn: string; author: string; title: string; } let books: Array<IBook> = [{ isbn: "1", author: "Robin Wieruch", title: "The Road to React", },{ isbn: "2", author: "Kyle Simpson", title: "You Don't Know JS: Scope & Closures", },{ isbn: "3", author: "Andreas A. Antonopoulos", title: "Mastering Bitcoin", }] const getBooks = ({ response }: { response: any }) => { response.body = books } const getBook = ({ params, response }: { params: { isbn: string }; response: any }) => { const book: IBook | undefined = searchBookByIsbn(params.isbn) if (book) { response.status = 200 response.body = book } else { response.status = 404 response.body = { message: `Book not found.` } } } const addBook = async ({ request, response }: { request: any; response: any }) => { const body = await request.body() const book: IBook = body.value books.push(book) response.body = { message: 'OK' } response.status = 200 } const updateBook = async ({ params, request, response }: { params: { isbn: string }; request: any; response: any }) => { let book: IBook | undefined = searchBookByIsbn(params.isbn) if (book) { const body = await request.body() const updateInfos: { author?: string; title?: string } = body.value book = { ...book, ...updateInfos} books = [...books.filter(book => book.isbn !== params.isbn), book] response.status = 200 response.body = { message: 'OK' } } else { response.status = 404 response.body = { message: `Book not found` } } } const deleteBook = ({ params, response }: { params: { isbn: string }; response: any }) => { books = books.filter(book => book.isbn !== params.isbn) response.body = { message: 'OK' } response.status = 200 } /* return the book if found and undefined if not */ const searchBookByIsbn = (isbn: string): ( IBook | undefined ) => books.filter(book => book.isbn === isbn )[0] export { getBooks, getBook, addBook, updateBook, deleteBook } |
Why searchBookByIsbn is used in controller.ts?
This is a helper function to find the book by ISBN id and we call this function at line number 26.
Run the Deno code now
1 |
deno run --allow-env --allow-net app.ts |
Download source code from GitHub
If you like this article then please give your heart and share with your friends.

