Fetching and Deleting a Contact with AdonisJS | Full-Stack Google Contacts Clone with AdonisJS Framework (Node.js) and Quasar Framework (Vue.js)
In this lesson, we will learn how to create API endpoints for fetching the details of a contact and also deleting a contact. We will take advantage of our FindContact
middleware to check for the existence of the contact and get the model of the contact before the request lifecycle gets to the controller.
Let's start by creating a new branch for our repo:
# Make sure you are within your project
git checkout -b 15-fetching-and-deleting-a-contact
Adding New Route Endpoints
We will add two new route definitions to our api/start/routes.ts
file. Open the api/start/routes.ts
. Refer to this snapshot. Add the following lines to end of the file:
Route.get('/contacts/:id', 'ContactsController.show').middleware(['findContact'])
Route.delete('/contacts/:id', 'ContactsController.destroy').middleware(['findContact'])
Above, we are adding a GET /contacts/:id
endpoint for fetching all the details of a contact. We assign the show
method in the ContactsController
class as the handler. The full details of the contact will be used to populate the details page of the contact on the frontend. We are also adding a DELETE /contacts/:id
endpoint for deleting a contact. The destroy
method in the ContactsController
class is assigned as the route handler. Both route definitions are attached the findContact
middleware for getting the Contact
model before the request lifecycle gets to the controller.
Improving the FindContact.ts
middleware
Next, we will improve the error handling in the api/app/Middleware/FindContact.ts
middleware. The following changes are made. Refer to this [snapshot] (github.com/ndianabasi/google-contacts/blob/..) for the updated file.
- const contact = await Contact.findOrFail(id)
- if (!contact) {
+ let contact: Contact
+ try {
+ contact = await Contact.findOrFail(id)
+ } catch (error) {
return response.notFound({ message: 'Unknown contact was requested' })
}
This call, await Contact.findOrFail(id)
, automatically throws an error if the id
is not found in the contacts
table. Because of this, we need to wrap it with a try...catch
block if we are to catch the error and handle it ourselves, else the old line, if(!contact) {...}
will not be reached if an error is thrown. In the catch
block, we manually return 400
(bad request) error with a message.
Updating the show
and destroy
methods
Now, we will update the show
and destroy
methods in the ContactsController
file.
Open the api/app/Controllers/Http/ContactsController.ts
file. Refer to this snapshot for these updates.
Update the show
method to the following:
public async show({ response, requestedContact }: HttpContextContract) {
try {
return response.ok({ data: requestedContact })
} catch (error) {
Logger.error('Error at ContactsController.show:\n%o', error)
return response.status(error?.status ?? 500).json({
message: 'An error occurred while deleting the contact.',
error: process.env.NODE_ENV !== 'production' ? error : null,
})
}
}
On Line 83, we make sure that we destructure requestedContact
from the HttpContext
. Next, we simply return the requestedContact
without any other modifications: return response.ok({ data: requestedContact })
.
Update the destroy
method to the following:
public async destroy({ response, requestedContact }: HttpContextContract) {
try {
await requestedContact?.delete()
return response.created({ message: 'Contact was deleted', data: requestedContact?.id })
} catch (error) {
Logger.error('Error at ContactsController.destroy:\n%o', error)
return response.status(error?.status ?? 500).json({
message: 'An error occurred while deleting the contact.',
error: process.env.NODE_ENV !== 'production' ? error : null,
})
}
}
In Line 154, we make sure that we destructure requestedContact
from the HttpContext
. Then, on Line 156, we call the static delete
method on the Contact
model to delete the contact: await requestedContact?.delete()
. Then, we return a response with a custom message.
Testing the Endpoint with Postman
Next we will use Postman
to test the two endpoints we have created and programmed. Launch Postman
and make sure that the Google Contacts Clone
workspace is active. Also ensure that your API server is running. If it is not running, do the following:
cd api
yarn serve
Fetching a Contact
For the GET /contacts/:id
endpoint, do the following:
- Right-click on the
CRUD
collection and clickAdd Request
. EnterFetch Contact
as the name. - Ensure that the request method is
GET
. Enter{{baseURL}}/contacts/:id
in theRequest URL
field. ThePath Variable
table will be displayed under theParams
tab. If not shown, switch to theParams
tab below therequest URL
manually. We need to populate theid
of the contact we want to update. - Open
MySQL Workbench
and open the connection we created for this series. Expand thegoogle_contacts_app
schema, and browse thecontacts
table. Copy theid
of any contact from thecontacts
table. Now, switch back to
Postman
and paste theid
into theVALUE
column for theid
parameter row. EnterContact ID
underDESCRIPTION
. See the image below:As seen in the screenshot above, you can define an environmental variable (
contactId
) to hold theContact ID
so that you update it centrally. To do this, follow these steps:- Make sure that your active
environment
is thedefault
environment we created earlier. - Click the
eye
icon at the top-right corner to see theEnvironment
dialog and clickEdit
to edit theenvironment
. Add a new variablecontactId
and paste theid
you copied from the database underINITIAL VALUE
. Save the `environment. - If you need to update the variable, make sure that you change both the
INITIAL VALUE
andCURRENT VALUE
.
- Make sure that your active
Now, click on the
Fetch Contact
request and enter{{contactId}}
under theVALUE
column for theid
variable in thePath Variables
area.Save the request.
Click
Send
to send the request. If all went well, you should get a response like this:
{
"data": {
"id": "ckuyj7r9w00000ovod2eo0yf5",
"first_name": "Morris",
"surname": "Fahey",
"company": "Baumbach, Borer and Gleason",
"job_title": "Forward Response Orchestrator",
"email1": "Morris_Fahey@gmail.com",
"email2": null,
"phone_number1": "(701) 351-4525",
"phone_number2": null,
"country": "Ethiopia",
"street_address_line1": "162 Schoen Curve",
"street_address_line2": "18962 Larry Squares",
"city": null,
"post_code": "31207",
"state": "Iowa",
"birthday": null,
"website": "https://ozella.biz",
"notes": null,
"created_at": "2021-10-19T21:21:16.000+01:00",
"updated_at": "2021-10-19T21:21:16.000+01:00"
}
}
Congratulations! You have fetched a contact from the database.
Deleting a Contact
For the DELETE /contacts/:id
endpoint, do the following:
- Right-click on the
CRUD
collection and clickAdd Request
. EnterDelete Contact
as the name. - Ensure that the request method is
DELETE
. Enter{{baseURL}}/contacts/:id
in theRequest URL
field. ThePath Variable
table will be displayed under theParams
tab. If not shown, switch to theParams
tab below therequest URL
manually. Enter
{{contactId}}
under theVALUE
column for theid
variable in thePath Variables
area. This assumes that you have defined acontactId
environment variable. Else, manually enter theid
value instead of{{contactId}}
. See the following screenshot:Save and send the request.
If all went well, you should get a response like this:
{ "message": "Contact was deleted", "data": "ckuyj7r9w00000ovod2eo0yf5" }
Congratulations! You have successfully deleted a contact.
Attempt to delete the contact again by resending the request with the same
id
. You should get the following 404 error:{ "message": "Unknown contact was requested" }
Awesome. Our middleware
is working well and has thrown an error because that id
has been deleted.
We have successfully created API endpoints and demonstrated how AdonisJS makes Database operations so easy as seen in our controller. With just one to two lines of code, we were able to return a response from the show
and destroy
methods. This was also possible because we refactored the process of getting the requestedContact
into a middleware.
This concludes this lesson. In the next lesson, we will learn how to created a factory and seeder for mass creation of contacts as we continue to build and test our application. We will also learn how to list all the contacts with the help of pagination. This lesson will be interesting. ๐๐ Don't miss it. ๐
Save all your files, commit, merge with the master branch, and push to the remote repository (Github).
git add .
git commit -m "feat(api): complete fetching and deletion of contacts"
git push origin 15-fetching-and-deleting-a-contact
git checkout master
git merge master 15-fetching-and-deleting-a-contact
git push origin master