Coder Social home page Coder Social logo

winterrdog / high-ride-api Goto Github PK

View Code? Open in Web Editor NEW
3.0 1.0 0.0 343 KB

A simplified ride-sharing backend API developed in NestJS, which includes features like user registration, ride requests, and driver availability management. Something like the Uber trip system

License: The Unlicense

JavaScript 1.88% TypeScript 98.12%

high-ride-api's Introduction

high-ride Logo

A simplified ride-sharing backend RESTFUL API developed in NestJS, which includes features like user registration, ride requests, and driver availability management.

Description

high-ride-api is a simplified ride-sharing backend API developed in NestJS, which includes features like user registration, ride requests, and driver availability management. The API is developed using NestJS, a progressive Node.js framework for building efficient, reliable, and scalable server-side applications. It uses MongoDB as the database service and is developed using TypeScript.

The API takes in the data in JSON format and returns the data in JSON format as well.

Requirements

  • NodeJS( >= 16.0.0 )
  • MongoDB( >= 4.4.6 )
  • npm( >= 7.10.0 )
  • Git( >= 2.25.1 )
  • Postman( >= 8.10.0 ) or any other API testing tool e.g. Insomnia, HTTPie( I used this for testing the API ), etc.

Installation of NodeJS

  • Follow the instructions given here to install NodeJS on your system.

Installation of MongoDB

  • Follow the instructions given here to install MongoDB on your system.

Setting up database service

  • Create a .env file in the root directory of the project.
  • Copy the contents of .env.example to .env file.
  • Replace the value of JWT_SECRET to a random( but secure ) string of your choice. This will be used to sign the JWT tokens.
  • By default, the database service is configured to run on mongodb://localhost:27017/high-ride-api which won't need any authentication. If you want to change the database service URL, replace the value of DB_URI in .env file.
  • On Unix, start the MongoDB service.
    sudo systemctl start mongod
  • On Windows, in order to start the MongoDB service, follow the instructions given here or here.

Setting up the project

  • Clone the repository.
    git clone https://github.com/winterrdog/high-ride-api.git
  • Navigate to the project's root directory.
    cd high-ride-api
  • Install the dependencies.
    $ npm i

Running the app

  • By default, the app is configured to run on http://localhost:5000. If you want to change the port, replace the value of PORT in your .env file.

    # development mode
    $ npm start
    
    # watch mode
    $ npm run start:dev
    
    # production mode
    $ npm run start:prod

Routes and their description

User management routes

  • POST /user/register - Register a new user. Accessible to everyone. Send a POST request with the following data in JSON format.

    {
      "firstName": "John",
      "lastName": "Doe",
      "email": "[email protected]",
      "password": "johndoe123",
      "phoneNumber": "07000000000",
      "role": "passenger"
    }

    The role field can be either passenger or driver.

    The server will respond with the registered user and a JWT token. Status code 201 will be returned if the user is successfully registered.

  • GET /user/profile - Get the profile of the logged-in user. Only authenticated users can access this route. The server will return the profile of the logged-in user. Status code 200 will be returned if the user is successfully fetched. For instance:

    {
      "firstName": "John",
      "lastName": "Doe",
      "email": "[email protected]",
      "phoneNumber": "1234567890",
      "role": "driver",
      "driverStatus": "not applicable",
      "id": "64eb94ca0a86e88cd4d80944",
      "dateCreated": "2023-08-27T18:24:10.598Z",
      "lastModified": "2023-08-27T18:24:10.598Z"
    }
  • PATCH /user/profile/driver - Update the profile of the logged-in user who's a driver roles. Only authenticated driver role users can access this route. Send a PATCH request with the following data in JSON format.

    {
      "driverStatus": "available"
    }

    The driverStatus field can be either available or unavailable.

    The server will respond with the updated profile of the logged-in user. Status code 200 will be returned if the user is successfully updated. For instance:

      {
        "firstName": "John",
        "lastName": "Doe",
        "email": "[email protected]",
        "phoneNumber": "1234567890",
        "role": "driver",
        "driverStatus": "available",
        "id": "64eb94ca0a86e88cd4d80944",
        "dateCreated": "2023-08-27T18:24:10.598Z",
        "lastModified": "2023-08-27T18:24:10.598Z"
      }

Ride management routes

  • GET /rides/ - Get the list of all available rides. Only authenticated driver role users can access this route. The server will return the list of all available rides. Status code 200 will be returned if the rides are successfully fetched otherwise it'll return a 404. For instance:

      [ 
        {
          "passenger": {
            "firstName": "Lyndon",
            "lastName": "Darren",
            "email": "[email protected]",
            "phoneNumber": "1234567890",
            "role": "passenger",
            "driverStatus": "not applicable",
            "id": "64ec26c23ef09575c4838c64"
          },
          "driver": null,
          "pickUpLocation": {
            "latitude": 37.7749,
            "longitude": -122.4194,
            "locationName": "San Francisco",
            "country": "United States"
          },
          "dropOffLocation": {
            "latitude": 34.0522,
            "longitude": -118.2437,
            "locationName": "Los Angeles",
            "country": "United States"
          },
          "rideStatus": "accepted",
          "createdAt": "2023-08-28T04:50:22.223Z",
          "updatedAt": "2023-08-28T09:14:29.816Z",
          "id": "64ec278e855903b8781efbc8"
        }
    ]

    The driver field will be null if the ride is not accepted by any driver. Otherwise, it'll contain the driver's profile like in this case:

      {
        "passenger": {
          "firstName": "Lyndon",
          "lastName": "Darren",
          "email": "[email protected]",
          "phoneNumber": "1234567890",
          "role": "passenger",
          "driverStatus": "not applicable",
          "id": "64ec26c23ef09575c4838c64"
        },
        "driver": {
          "firstName": "John",
          "lastName": "Doe",
          "email": "",
          "phoneNumber": "1234567890",
          "role": "driver",
          "driverStatus": "available",
          "id": "64ec26c23ef09575c4838c65"
        },
        "pickUpLocation": {
          "latitude": 37.7749,
          "longitude": -122.4194,
          "locationName": "San Francisco",
          "country": "United States"
        },
        "dropOffLocation": {
          "latitude": 34.0522,
          "longitude": -118.2437,
          "locationName": "Los Angeles",
          "country": "United States"
        },
        "rideStatus": "accepted",
        "createdAt": "2023-08-28T04:50:22.223Z",
        "updatedAt": "2023-08-28T09:14:29.816Z",
        "id": "64ec278e855903b8781efbc8"
      }
  • POST /rides/ - Create a new ride. Only authenticated passenger role users can create a ride. Send a POST request with the following data in JSON format.

    {
      "pickUpLocation": {
        "latitude": 37.7749,
        "longitude": -122.4194,
        "locationName": "San Francisco",
        "country": "United States"
      },
      "dropOffLocation": {
        "latitude": 34.0522,
        "longitude": -118.2437,
        "locationName": "Los Angeles",
        "country": "United States"
      }
    }

    The server will respond with the created ride. Status code 201 will be returned if the ride is successfully created. For instance:

      {
        "passenger": {
          "firstName": "Lyndon",
          "lastName": "Darren",
          "email": "[email protected]",
          "phoneNumber": "1234567890",
          "role": "passenger",
          "driverStatus": "not applicable",
          "id": "64ec26c23ef09575c4838c64"
        },
        "driver": null,
        "pickUpLocation": {
          "latitude": 37.7749,
          "longitude": -122.4194,
          "locationName": "San Francisco",
          "country": "United States"
        },
        "dropOffLocation": {
          "latitude": 34.0522,
          "longitude": -118.2437,
          "locationName": "Los Angeles",
          "country": "United States"
        },
        "rideStatus": "accepted",
        "createdAt": "2023-08-28T04:50:22.223Z",
        "updatedAt": "2023-08-28T09:14:29.816Z",
        "id": "64ec278e855903b8781efbc8"
      }
  • PATCH /rides/:id - Update a ride's status. Only authenticated users can update a ride's status. Passengers can only mark rides as cancelled and drivers can mark rides as completed, accepted, and cancelled. Send a PATCH request with the following data in JSON format.

    {
      "rideStatus": "cancelled"
    }

    The rideStatus field can be either cancelled, accepted, or completed.

    The server will respond with the updated ride. Status code 200 will be returned if the ride is successfully updated. For instance:

      {
        "passenger": {
          "firstName": "Lyndon",
          "lastName": "Darren",
          "email": "[email protected]",
          "phoneNumber": "1234567890",
          "role": "passenger",
          "driverStatus": "not applicable",
          "id": "64ec26c23ef09575c4838c64"
        },
        "driver": null,
        "pickUpLocation": {
          "latitude": 37.7749,
          "longitude": -122.4194,
          "locationName": "San Francisco",
          "country": "United States"
        },
        "dropOffLocation": {
          "latitude": 34.0522,
          "longitude": -118.2437,
          "locationName": "Los Angeles",
          "country": "United States"
        },
        "rideStatus": "cancelled",
        "createdAt": "2023-08-28T04:50:22.223Z",
        "updatedAt": "2023-08-28T09:14:29.816Z",
        "id": "64ec278e855903b8781efbc8"
      }

    When the ride's accepted, the driver field will contain the driver's profile like in this case:

      {
        "passenger": {
          "firstName": "Lyndon",
          "lastName": "Darren",
          "email": "[email protected]",
          "phoneNumber": "1234567890",
          "role": "passenger",
          "driverStatus": "not applicable",
          "id": "64ec26c23ef09575c4838c64"
        },
        "driver": {
          "firstName": "John",
          "lastName": "Doe",
          "email": "[email protected]",
          "phoneNumber": "1234567890",
          "role": "driver",
          "driverStatus": "available",
          "id": "64ec26c23ef09575c4838c65"
        },
        "pickUpLocation": {
          "latitude": 37.7749,
          "longitude": -122.4194,
          "locationName": "San Francisco",
          "country": "United States"
        },
        "dropOffLocation": {
          "latitude": 34.0522,
          "longitude": -118.2437,
          "locationName": "Los Angeles",
          "country": "United States"
        },
        "rideStatus": "accepted",
        "createdAt": "2023-08-28T04:50:22.223Z",
        "updatedAt": "2023-08-28T09:14:29.816Z",
        "id": "64ec278e855903b8781efbc8"
      }

    NOTE: A driver can only accept a ride if the driver's status is available. If the driver's status is unavailable, the server will respond with a 403 status code. A driver can only accept one ride at a time. If the driver tries to accept another ride, the server will respond with a 403 status code.

    When the ride's completed, the driver field will contain the driver's profile like in this case:

      {
        "passenger": {
          "firstName": "Lyndon",
          "lastName": "Darren",
          "email": "[email protected]",
          "phoneNumber": "1234567890",
          "role": "passenger",
          "driverStatus": "not applicable",
          "id": "64ec26c23ef09575c4838c64"
        },
        "driver": {
          "firstName": "John",
          "lastName": "Doe",
          "email": "[email protected]",
          "phoneNumber": "1234567890",
          "role": "driver",
          "driverStatus": "available",
          "id": "64ec26c23ef09575c4838c65"
        },
        "pickUpLocation":
        {
          "latitude": 37.7749,
          "longitude": -122.4194,
          "locationName": "San Francisco",
          "country": "United States"
        },
        "dropOffLocation": {
          "latitude": 34.0522,
          "longitude": -118.2437,
          "locationName": "Los Angeles",
          "country": "United States"
        },
        "rideStatus": "completed",
        "createdAt": "2023-08-28T04:50:22.223Z",
        "updatedAt": "2023-08-28T09:14:29.816Z",
        "id": "64ec278e855903b8781efbc8"
      }

    When the ride's cancelled, the driver field will still be set to null like in this case:

      {
        "passenger": {
          "firstName": "Lyndon",
          "lastName": "Darren",
          "email": "[email protected]",
          "phoneNumber": "1234567890",
          "role": "passenger",
          "driverStatus": "not applicable",
          "id": "64ec26c23ef09575c4838c64"
        },
        "driver": null,
        "pickUpLocation": {
          "latitude": 37.7749,
          "longitude": -122.4194,
          "locationName": "San Francisco",
          "country": "United States"
        },
        "dropOffLocation": {
          "latitude": 34.0522,
          "longitude": -118.2437,
          "locationName": "Los Angeles",
          "country": "United States"
        },
        "rideStatus": "cancelled",
        "createdAt": "2023-08-28T04:50:22.223Z",
        "updatedAt": "2023-08-28T09:14:29.816Z",
        "id": "64ec278e855903b8781efbc8"
      }

NOTE: By default, the database will be empty. So you'll need to create a ride first otherwise you'll get 404 error status code with a message No rides found.

Authentication and Authorization implementation

  • Every JWT token will contain the following fields:
    {
      "sub": "64ec26c23ef09575c4838c64",
      "role": "passenger",
      "iat": 1629999999,
      "exp": 1630000000
    }
    The sub field will contain the user's id, the role field will contain the user's role, the iat field will contain the time at which the token was issued, and the exp field will contain the time at which the token will expire.
  • The API uses JWT for authentication and authorization. The JWT tokens are signed using the JWT_SECRET value provided in the .env file.
  • The API uses PassportJS for authentication and authorization. The PassportJS strategy used is JWTStrategy which is configured in src/auth/strategies/jwt.strategy.ts file.
  • I chose to use JWT for authentication and authorization because it's stateless and can be used in microservices architecture. It's also scales well in case the API needs to be scaled in the future.

Testing the app

# run unit tests
$ npm test

Author

winterrdog - GitHub

License

high-ride-api is of Unlicense.

high-ride-api's People

Contributors

winterrdog avatar

Stargazers

 avatar  avatar  avatar

Watchers

 avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.