Ready to level up in your coding journey ? If you've already mastered the frontend—building sleek interfaces, responsive layouts, and user experiences that feel effortless. Now it’s time to take the next step: connecting those front-end experiences to real data.
In this article, we're going to deep dive into the process of building a Node.js API from the ground up. Get ready to get your hands dirty with Node.js, set up a MySQL database, and explore Swagger for testing and documentation. Furthermore, You want to know how to create an API in JAVA environment? No worries ,we’ve got that covered for you !
By the end of this, you would have gained a solid understanding of how the back-end powers your front-end. —and you will be ready to build production ready APIs—and to be that go to full stack developer!
Building REST APIs in Node
Step 1 - Setting Up Your Environment and Database Foundation
The first question that may come up is What is Node.js and why use it here?
Node.js is a runtime that lets you run JavaScript on the server. It's fast, event-driven, and perfect for building APIs. Node.js comes with npm, a huge ecosystem of open-source libraries. Node.js uses event-driven architecture. Instead of waiting for operations like file reads or database queries to complete, it registers callbacks and moves on. This makes Node.js extremely fast and efficient for I/O-heavy applications like APIs. Node.js follows the CommonJS module system where you can organize code into reusable pieces as .js extension files
Before we write any API code, we need to get our environment ready and think about where our data will live.
First, make sure you have Node.js installed. If not, grab it from the official website(Go to https://nodejs.org ). It comes with npm (or you can use yarn), which we'll need to manage project packages. Install it with default settings.
node -v and npm -v are the command used to verify the proper installation of node.
Next, let's talk database. We'll be using MySQL. Set up a MySQL instance if you don't have one running already. Install it from https://dev.mysql.com/downloads/mysql/ if you havn’t already.
Now, the fun part: designing our database schema (CREATE DATABASEdb_name;) ! When you get a requirement to manage something like a user, item, or dealer, you need to think about the attributes for that entity. You'll have your basic attributes like name, email, or phone number. But there's more to consider for a robust system.
Here’s a sample table schema
Now, let’s not forget about the crucial technical attributes! Here are some of the salient attributes:
- created_at: A timestamp recording when the data was initially created.
- updated_at: A timestamp showing when the data was last modified.
- created_by: A user ID indicating who created this record.
- updated by: A user ID indicating who last updated this record.
These timestamps and user IDs are incredibly helpful for tracking changes and debugging!
Another really important piece of practical advice is about handling deletion. Instead of completely wiping a record from your database when someone hits "delete", it's often better to use a soft delete strategy. This involves adding an is_active flag to your table. When a delete is requested, you simply set this flag to false. The record is now effectively disabled and won't show up in your active data lists, but the data is still there if you ever need to recover it or reference it later. Genius, right?
Finally, within your Node.js project, you'll need a library to connect to your MySQL database. Popular choices include mysql2 or an ORM (Object-Relational Mapper) like Sequelize.
Connecting to NodeJS to mysql using mysql2
Step 2 - Building the Core API Operations (CRUD)
This is where we build the heart of our API – the operations that let us interact with our data. You've probably heard of CRUD: Create, Read, Update, and Delete. These are the four fundamental actions we'll implement.
📦 Let's break them down:
Creating HTTP server and handling requests in server.js
Here a server is set up that listens for requests. url.parse extracts the URL path (e.g., /users) to handle different routes. In the logic for implementation of GET active users are retrieved from the database and a 200 OK response is sent with JSON data.
In the POST implementation a new user's name and email is received and inserted into the database. A response as 201 Created is then sent back
Step 3 - Implementing Data Validation
Just receiving data isn't enough; you have to make sure that data is actually valid and safe before you put it in your database! This is where validation comes in. It protects your database and ensures data integrity.
Validating input data is crucial. For example, validating the format of an email ID using a regular expression. Another example would be shows validation for an address field, checking for unexpected characters.
A smart way to handle validation is to put your validation functions into a separate file, like a helpers.js file. This keeps your main API endpoint code cleaner and makes your validation logic reusable. You can have specific functions like validateEmail or validateAddress.
If the incoming data doesn't pass validation, your API should respond with a 400 Bad Request status code. This clearly tells the client that the issue was with the data they sent.
Validation for username, password check
This function validateUserInput() checks if a username and password meet basic security and formatting rules. It ensures the username is 3–20 characters long and only contains letters, numbers, or underscores. If any condition fails, it returns a list of error messages for easy handling in your API.
Step 4 - Testing and Documenting Your API with Swagger
Okay, you've built your API! How do you test it and, just as importantly, let other developers (or even your future self!) know how to use it? Enter Swagger!
One of the most commonly used tools for testing NodeJS APIs is Swagger as a tool for both testing APIs and maintaining API documentation.
You can integrate Swagger UI into your Node.js project. It allows you to describe your API's endpoints, parameters, and expected request/response formats. The cool part is that Swagger UI then gives you a visual interface where you can manually test your API endpoints directly in the browser. For this first you need to install and set up swagger (npm install swagger-ui-express swagger-jsdoc)
Then you need to create a file called swagger.js(or something similar) to define your API documentation like the API definitions like the API versions, the title and descriptions and the server url. Next, we need to set up swagger in server.js.
Setting up swagger in server.js
It's a fantastic way to see your API in action and helps generate documentation automatically from your code or specification.
Step 5 - Beyond the Basics - Building Production-Ready APIs
You've got the core CRUD operations working, you're validating data, and you can test with Swagger. That's a huge step! But to build an API that's ready for the real world (a.k.a. production), there are a few more crucial things to consider.
Addressing Crucial Security Aspects: This is non-negotiable!
🔐 Authentication: How do you verify who is calling your API? Token-based methods like JSON Web Tokens (JWT) are common.
Here is a code snippet that finds the user, creates a JWT sign-in token and return it. The authenticate middleware then verifies the token and attaches the user info to the request
🔐 Authorization: Once you know who they are, what are they allowed to do? You'll need logic to control access based on user roles or permissions.
Authorization based on RBAC using middleware
Protecting Against Vulnerabilities: Be mindful of common attacks like SQL injection (especially if building raw queries) and always sanitize user input thoroughly. Using parameterized queries protects against SQL injection.
Rate Limiting: Protect your API from being overwhelmed by too many requests from a single source.
Comprehensive Error Handling: Users expect clear feedback when something goes wrong.
- Implement consistent, standardized error responses (often JSON) with appropriate HTTP status codes (like 401 Unauthorized, 403 Forbidden, 404 Not Found, and 5xx for server errors).
Implementing Automated Testing: Manual testing with Swagger is great for exploration, but automated tests are essential for reliability as your API grows.
- Unit Tests: Test individual functions like your validation helpers.
- Integration Tests: Test your API endpoints to ensure they work correctly end-to-end.
Considering Scalability and Performance: As your API usage grows, you'll need to think about performance.
- Optimize database queries (e.g., adding indexes).
- Consider caching frequently accessed data.
Logging and Monitoring: Set up logging to track requests, responses, and errors in production. Monitoring helps you spot issues before your users do.
API Design Principles & Versioning: Sticking to principles like RESTful design helps make your API intuitive. Plan how you'll handle changes and updates to your API over time using versioning (e.g., /api/v1/dealers).
In this time and age of AI, here is a prompt to generate a NodeJS API
“Generate a full-featured Node.js REST API using Express.js with following features:
- Define RESTful routes for a users resource.
- Implement complete CRUD endpoints for managing products
- Use MySQL as the database, and integrate it using either mysql2 or Sequelize
- Ensure appropriate HTTP status codes and error messages are returned
- Include at least one unit test for each CRUD route.”
Building REST APIs in Java
Up until now we focused on building your first API using Node.js and MySQL. It covered setting up the Node.js environment, designing a database schema with technical attributes and soft delete, implementing CRUD operations (Create, Read, Update, Delete), implementing data validation, and testing/documenting with Swagger.
Building APIs is a fundamental skill, and while Node.js is a popular choice, Java is another robust, object-oriented programming language widely used, especially in enterprise applications, with excellent support for building scalable and secure REST APIs using frameworks like Spring Boot.
If you're building an API in Java, you'll need a set of tools and a framework to simplify the process, similar to how Node.js uses libraries like mysql2 or ORMs like Sequelize and relies on npm/yarn for package management.
Step 1 - Setting Up Your Java Environment and Project
Before coding, you need the right environment and tools:
Java Development Kit (JDK): As the first step we need to make sure JDK is downloaded and installed (You can install java from https://jdk.java.net). This is essential for compiling and running Java code. Ensure environment variables (JAVA_HOME) are set correctly. (java -version and javac -version are used to check the installation)
IDE: Next comes working around a comfortable IDE. An Integrated Development Environment like IntelliJ IDEA, Eclipse, or VS Code is recommended for writing and managing your code.
Build Tool: Maven or Gradle are used for dependency management in Java projects. Maven uses a pom.xml file to declare project dependencies.
A snippet of a pom.xml where the maven dependencies are used
Framework: A framework like Spring Boot simplifies creating web applications, including RESTful services. Spring autoconfigures everything and has an embedded Tomcat server and also implicitly supports REST. Visit https://start.spring.io , choose com.example as group and demo-api as artifact. Alternatively, libraries like Jersey provide implementations for building RESTful web services using the Java API for RESTful Web Services (JAX-RS) specification.
Server: To run a web service, you need a server. Apache Tomcat is one of the most common choices for deploying the Java API. You would typically download and configure Tomcat within your IDE. Then this requires deploying your WAR file to webapps/ after which you start the server.
Here is a sample project structure
To start a project, you can use tools like the Spring Initializer for a Spring Boot project. If using Eclipse for a non-Spring Boot (e.g., Jersey-based) API, you'd create a Dynamic Web Project. In a Dynamic Web Project, configuring the web.xml deployment descriptor is important. You also need to add necessary libraries, like the Jersey JAR files, to your project's library folder.
Step 2 - Building the Core API Operations (CRUD)
Java REST APIs also implement the fundamental CRUD operations, but they do so using specific annotations and structures provided by the chosen framework (like Spring Boot or Jersey). Now let’s dig in deep into some of these key annotations.
📦 Controllers: In frameworks like Spring Boot, you create classes annotated with @RestController to handle incoming requests and define your API endpoints. These classes contain methods that correspond to different API operations. In a Jersey-based approach, classes that will act as web service resources can be annotated with @Path to define the base URL path for the resource.
@RestController makes the class a REST API controller. @GetMapping("/hello") binds HTTP GET requests to the /hello endpoint. The sayHello() method returns a simple "Hello, Dev.to!" message as the response.
HTTP Methods: Just like in Node.js, Java APIs use HTTP methods like GET, POST, PUT, and DELETE. These are mapped to controller methods using specific annotations.
- @GetMapping: Binds HTTP GET requests to a specific endpoint, used for retrieving data. This is similar to how Node.js uses GET endpoints for fetching data. In Jersey, the @GET annotation is used for read-only access to resources.
- @PostMapping: Handles HTTP POST requests, typically used for adding new data. This mirrors the Node.js approach for creating new records. POST can update or create a new resource if not present.
- Other methods like PUT (often for updates) and DELETE (for removal) are also part of REST principles.
To handle POST requests, we use @PostMapping. Here’s an example where we accept user data via POST and return the created user
Handling Request Data: To receive data sent in the request body (like for POST requests), you can use annotations like @RequestBody in Spring Boot. Methods can also accept parameters passed in the URL using annotations like @QueryParam in a Jersey-based API.
Receiving Json payload in a POST request using @RequestBody
Send parameters via URL using @Requestparam
Specifying Response Type: Annotations like @Produces can specify the MIME type of the response being sent back by an API method, such as text/xml, application/json, or text/html. Spring boot auto converts POJOs to JSON using Jackson (no need to declare MIME unless needed)
Specifying the resource type
Defining Resources: The concept of a "resource" is key in RESTful APIs. A resource is anything that can be named and stored, like a specific value or data being sent or received. You would create Java classes to represent these data structures (e.g., a User class with name and email attributes).
Step 3 - Beyond the Basics
Now you have built the core API operations are built, but wait there’s more! We need to look at several other crucial aspects are needed for a complete and robust API:
🔐 Data Validation: Ensuring incoming data is valid and safe is essential for data integrity. While in Node.js validation logic can be used directly, in Java Spring Boot validation is done using annotations like @Valid and @NotNull as a next step. Consistent error responses, like a 400 Bad Request status code for invalid data, are important. This requires that validation dependency be added in the pom.xml if not already present. Spring will automatically return a 400 Bad Request if validation fails. You can also have your own customized error responses using @ExceptionHandler annotation.
Adding validation annotations in the model
Use @Valid annotation in the controller
🚀 Database Connection: To persist data, your API needs to connect to a database. For relational databases in Java, JPA (Java Persistence API) is mentioned as a way to store data. This is analogous to using libraries like mysql2 or ORMs like Sequelize in the Node.js example. These are the steps to persist data - Step 1: Add Spring Data JPA & H2/MySQL Driver - Step 2: Configure Database in application.properties - Step 3: Annotate Entity Class - Step 4: Create Repository Interface - Step 5: Update Controller to Persist Users
🛠️Error Handling: Implementing consistent error responses with appropriate HTTP status codes (like 404 Not Found, 5xx server errors) is vital. Spring Boot offers features like @ControllerAdvice for customizing error responses. @ControllerAdvice is for Global Exception Handling
Step 4 - Testing Your API
Phew! We finally built the API, now we move to the next crucial part.
🧪 Testing is crucial to ensure your API works as expected. You can test Java APIs using tools like Postman or the curl command line tool, especially for testing methods like POST by sending JSON data. You can also run your application on the configured server (like Tomcat) and access the endpoints directly through a web browser, particularly for GET requests.
Example curl command that will return the JSON response with the created user
Now let us summarize, The process starts with setting up the development environment, which includes installing the Java Development Kit (JDK), choosing a suitable Integrated Development Environment (IDE) like IntelliJ IDEA, Eclipse, or VS Code, and selecting a build tool such as Maven or Gradle for managing project dependencies and building the application, Then you select a framework like Spring Boot or using libraries like Jersey, configuring a server like Tomcat. The server setup depends on the chosen framework. Defining REST endpoints is done using annotations. In Spring Boot, you use annotations like @RestController, @GetMapping, @PostMapping, @RequestBody, and @PathVariable to create methods that respond to HTTP requests. In Jersey, annotations such as @Path, @GET, @POST, @Produces, and @QueryParam serve the same purpose, providing a declarative way to define routes and handle incoming data.
A critical concept in RESTful API design is the idea of a resource, typically represented by Java classes such as User, Product, or Order. These classes model the data structure and may serve as both Data Transfer Objects (DTOs) and database entities. Data validation ensures that incoming requests are safe and well-formed. Spring Boot simplifies validation using annotations like @NotNull, @Email, and @Valid, returning standardized error responses like 400 Bad Request when validation fails.
To persist data, APIs typically connect to a relational database using Java Persistence API (JPA). Database configuration is done in the application.properties file, allowing the app to connect to databases such as H2 (in-memory), MySQL, or PostgreSQL. Spring Boot allows global error handling using @ControllerAdvice and @ExceptionHandler, enabling consistent and descriptive error responses across the application.
In addition to these core features, modern APIs should also include authentication and authorization mechanisms. Spring Security is often used alongside JWT (JSON Web Tokens) to secure endpoints and manage user sessions. Cross-Origin Resource Sharing (CORS) settings may be configured to allow frontend applications to access backend APIs securely. Furthermore, to prevent abuse and ensure fair usage, rate limiting can be implemented using libraries like Bucket4j or Resilience4j.
Building APIs in Java provides a different set of tools and approaches compared to Node.js, offering another powerful way to create scalable and secure web services.
Now, here is a comprehensive prompt that you can use to create an API
“Generate a Java REST API using Spring Boot that performs CRUD operations on a Product entity.
- Use annotations like @RestController, @PostMapping, @GetMapping, @PutMapping, and @DeleteMapping. Include proper HTTP status codes in the responses. Implement CRUD endpoints for a customer entity. Use @Path, @GET, @POST, @PUT, and @DELETE annotations.
- Add input validation to a Spring Boot REST API using annotations like @NotNull, @Email, and @Valid for the User DTO. Return 400 Bad Request if validation fails.
- Generate unit and integration tests for a Spring Boot REST controller using JUnit 5 and Mockito. Test the UserController for GET, POST, PUT, and DELETE endpoints.”

Conclusion: Next Steps in Your API Development Journey
We've covered a lot of ground. You've learned how to set up your environment, design a smart database schema (including soft deletes and technical attributes), implement the core CRUD operations, add data validation (and organize it in helpers), and use Swagger for testing and documentation. We also touched on vital steps for making your API production-ready, like security and testing.
Building APIs is a skill that takes practice, so keep experimenting! Dive deeper into the security, testing, and deployment aspects we mentioned.
Happy coding, and best of luck building your next great API!