7. REST API (Connecting Frontend to Backend)
REST API Design Principles
In this section we will explore how to design, structure and maintain effective REST APIs using NestJS. REST (Representational State Transfer) is a popular architecture for client-server communication, and NestJS gives us all the tools to make robust REST APIs that are readable, scalable and easy to work with.
As our backend connects to the Flutter frontend using HTTP requests, a well-structured REST API is essential for clean integration and developer efficiency.
Understanding Rest Endpoints
Each REST endpoint represents a resource. In our project, resources include things like users and dietary restrictions. These resources follow predictable URL patterns and support standard HTTP methods.

Each route should follow a **noun-based, pluralised structure**, e.g., /users, /dietary-restrictions.
To keep things consistent for our frontend, it's important to structure API responses in a predictable format.
Common API considerations
When building your API endpoints, keep these points in mind
Validation: validate user input with DTO classes using class-validator decorators like @IsEmail, @IsString to prevent malformed data
Error Handling: Always catch and return error messages. Use HttpException in service or controller logic
Status Codes:
200: Request succeeded
201: Resource created
400: Invalid request data
404: Resource not found
500: Internal server error
Dio Client
As explained in the NestJS section, our frontend and and backend communicate through HTTP requests and responses. In order to connect to the HTTP client we are going to be using Dio, which means dart input output.
We need to download the Dio dependency in order to access this in Flutter. In pubspec.yaml file add the following line and then in your terminal, run flutter pub get be sure you are in the frontend folder.
In lib, create a new folder called core, this folder will be in charge of all core objects relevant across all domains of the app. Inside this folder create file named dio_client.dart. The content of this file should be as followed:
What this file is doing is making a dio object that follows the base URL of our server. All data transfer and communication will happen across this URL.
Services
Similar to the services we created in our NestJS user.service.ts file, we are going to create a user service for the flutter app, which will handle getting and sending all of user data.
To do this, inside of the lib directory create a folder named services, and inside this folder create a file named user_service.dart. We want to create methods which handle getting all of the users from the backend database, and another method to create a new user and send the information to our database.
First, create a class which imports the DIoClient we made in the earlier step.
Inside of this UserService class we want to first create a method that will handle getting all of the users from our database. Add this method to the class.
The return type in Dart is specified at the start of the method. For this method the return type Future needs to be used as retrieving data is an asynchronous function. Future is Darts way of saying that the data may not be retrieved instantly, but in the future. We know that the users will come in a list based off of how we are sending it using Prisma seen in section 5. Lastly, the dynamic type is used as the number of users may change and is not constant. Inside this method, our code is making a get request on the url /user and then returning the data it recieves.
Next lets make a method for creating a user. Add this next method to the User Service class.
The function returns a map where each key is a string and each value can be of any type. This structure is commonly used to represent JSON data, such as the response from an API. For example, when a user is created, the response might include fields like "id", "name", and "email", all stored in a Map<String, dynamic> so they can be accessed easily in your Dart code.
Now that we have all of the necessary code to connect our front end to the backend. Lets design our screen.
Last updated