Overview
The Adoptions API manages the relationship between users and pets when an adoption occurs. When a user adopts a pet, an adoption record is created, the pet is marked as adopted, and the pet is added to the user’s pets array.
Base Path: /api/adoptions
Source Files:
Routes: src/routes/adoption.router.js
Controller: src/controllers/adoptions.controller.js
Model: src/dao/models/Adoption.js
Adoption Model
The Adoption schema is a simple join table that links users to pets:
MongoDB-generated unique identifier
Reference to the User (ObjectId from Users collection)
Reference to the Pet (ObjectId from Pets collection)
Get All Adoptions
curl -X GET http://localhost:8080/api/adoptions
Endpoint
Retrieves a list of all adoptions in the system.
Response
Array of adoption objects
Example Response
{
"status" : "success" ,
"payload" : [
{
"_id" : "65def789abc123456" ,
"owner" : "6893eaba2ac0b16fa177be7a" ,
"pet" : "65abc123def456790"
},
{
"_id" : "65def789abc123457" ,
"owner" : "6893eaba2ac0b16fa177be7b" ,
"pet" : "65abc123def456791"
}
]
}
Error Responses
Show 500 Internal Server Error
Ha ocurrido un error en la petición, por favor ver detalle: [error]
Get Adoption by ID
curl -X GET http://localhost:8080/api/adoptions/65def789abc123456
Endpoint
Retrieves a single adoption record by its unique ID.
Path Parameters
The unique identifier (MongoDB ObjectId) of the adoption
Response
Adoption object with owner and pet references
Example Response
{
"status" : "success" ,
"payload" : {
"_id" : "65def789abc123456" ,
"owner" : "6893eaba2ac0b16fa177be7a" ,
"pet" : "65abc123def456790"
}
}
Error Responses
Show 404 Adoption Not Found
{
"status" : "error" ,
"error" : "Adoption not found"
}
Returned when the adoption with the specified ID doesn’t exist.
Show 500 Internal Server Error
Ha ocurrido un error en la petición, por favor ver detalle: [error]
Create Adoption
curl -X POST http://localhost:8080/api/adoptions/6893eaba2ac0b16fa177be7a/65abc123def456791
Endpoint
POST /api/adoptions/:uid/:pid
Creates a new adoption, linking a user to a pet. This endpoint performs several operations atomically:
Validates that the user exists
Validates that the pet exists
Checks that the pet is not already adopted
Adds the pet to the user’s pets array
Updates the pet’s adopted status to true and sets the owner
Creates an adoption record
Path Parameters
The unique identifier (MongoDB ObjectId) of the user adopting the pet
The unique identifier (MongoDB ObjectId) of the pet being adopted
Business Logic Flow
The adoption process implements the following logic (from src/controllers/adoptions.controller.js:23-38):
const { uid , pid } = req . params ;
const user = await usersService . getUserById ( uid );
if ( ! user ) return res . status ( 404 ). send ({ status: "error" , error: "user Not found" });
const pet = await petsService . getBy ({ _id:pid });
if ( ! pet ) return res . status ( 404 ). send ({ status: "error" , error: "Pet not found" });
if ( pet . adopted ) return res . status ( 400 ). send ({ status: "error" , error: "Pet is already adopted" });
user . pets . push ( pet . _id );
await usersService . update ( user . _id ,{ pets:user . pets })
await petsService . update ( pet . _id ,{ adopted: true , owner:user . _id })
await adoptionsService . create ({ owner:user . _id , pet:pet . _id })
res . send ({ status: "success" , message: "Pet adopted" })
Response
Example Response
{
"status" : "success" ,
"message" : "Pet adopted"
}
Error Responses
{
"status" : "error" ,
"error" : "user Not found"
}
Returned when the user with the specified ID doesn’t exist.
{
"status" : "error" ,
"error" : "Pet not found"
}
Returned when the pet with the specified ID doesn’t exist.
Show 400 Pet Already Adopted
{
"status" : "error" ,
"error" : "Pet is already adopted"
}
Returned when trying to adopt a pet that has already been adopted by another user.
Show 500 Internal Server Error
Ha ocurrido un error en la petición, por favor ver detalle: [error]
What Happens During an Adoption?
When you create an adoption, the following database operations occur:
1. User Update
The pet’s ObjectId is added to the user’s pets array:
// Before
{
"_id" : "6893eaba2ac0b16fa177be7a" ,
"first_name" : "Jerónimo" ,
"pets" : []
}
// After
{
"_id" : "6893eaba2ac0b16fa177be7a" ,
"first_name" : "Jerónimo" ,
"pets" : [
{ "_id" : "65abc123def456791" }
]
}
2. Pet Update
The pet is marked as adopted and the owner is set:
// Before
{
"_id" : "65abc123def456791" ,
"name" : "Buddy" ,
"adopted" : false ,
"owner" : null
}
// After
{
"_id" : "65abc123def456791" ,
"name" : "Buddy" ,
"adopted" : true ,
"owner" : "6893eaba2ac0b16fa177be7a"
}
3. Adoption Record Creation
A new adoption document is created:
{
"_id" : "65def789abc123458" ,
"owner" : "6893eaba2ac0b16fa177be7a" ,
"pet" : "65abc123def456791"
}
All three operations must succeed for the adoption to be complete. If any operation fails, an error is returned and the transaction should be rolled back (though the current implementation doesn’t use MongoDB transactions).
Complete Adoption Example
Step 1: Check Available Pets
curl -X GET http://localhost:8080/api/pets
Step 2: Check User Profile
curl -X GET http://localhost:8080/api/users/6893eaba2ac0b16fa177be7a
Step 3: Create Adoption
curl -X POST http://localhost:8080/api/adoptions/6893eaba2ac0b16fa177be7a/65abc123def456791
Response:
{
"status" : "success" ,
"message" : "Pet adopted"
}
Step 4: Verify Adoption
# Check user now has the pet
curl -X GET http://localhost:8080/api/users/6893eaba2ac0b16fa177be7a
# Check pet is now adopted
curl -X GET http://localhost:8080/api/pets
# Check adoption record
curl -X GET http://localhost:8080/api/adoptions
Implementation Details
Controller Source
The Adoptions controller (src/controllers/adoptions.controller.js) implements:
Show createAdoption - Lines 23-39
const createAdoption = async ( req , res ) => {
try {
const { uid , pid } = req . params ;
const user = await usersService . getUserById ( uid );
if ( ! user ) return res . status ( 404 ). send ({ status: "error" , error: "user Not found" });
const pet = await petsService . getBy ({ _id:pid });
if ( ! pet ) return res . status ( 404 ). send ({ status: "error" , error: "Pet not found" });
if ( pet . adopted ) return res . status ( 400 ). send ({ status: "error" , error: "Pet is already adopted" });
user . pets . push ( pet . _id );
await usersService . update ( user . _id ,{ pets:user . pets })
await petsService . update ( pet . _id ,{ adopted: true , owner:user . _id })
await adoptionsService . create ({ owner:user . _id , pet:pet . _id })
res . send ({ status: "success" , message: "Pet adopted" })
} catch ( error ) {
res . status ( 500 ). send ( "Ha ocurrido un error en la petición, por favor ver detalle: " , error )
}
}
Router Configuration
Routes are defined in src/routes/adoption.router.js:
router . get ( '/' , adoptionsController . getAllAdoptions );
router . get ( '/:aid' , adoptionsController . getAdoption );
router . post ( '/:uid/:pid' , adoptionsController . createAdoption );
Model Definition
The Adoption model (src/dao/models/Adoption.js) is simple:
const schema = new mongoose . Schema ({
owner: {
type:mongoose . SchemaTypes . ObjectId ,
ref: 'Users'
},
pet: {
type:mongoose . SchemaTypes . ObjectId ,
ref: 'Pets'
}
})
Considerations
No DELETE endpoint: The current implementation doesn’t provide a way to reverse an adoption (un-adopt a pet). If this functionality is needed, you would need to:
Remove the pet from the user’s pets array
Set the pet’s adopted status to false and clear the owner
Delete the adoption record
No transactions: The adoption process performs multiple database operations sequentially without using MongoDB transactions. If one operation fails after others succeed, you may end up with inconsistent data. Consider implementing transactions for production use.
One pet, one owner: A pet can only be adopted by one user at a time. The check if(pet.adopted) prevents a pet from being adopted twice.
Users API View user profiles and their adopted pets
Pets API Browse available pets for adoption