# Networking Programming - API and DB
## API
<div style="text-align:center;">
<img src="https://hackmd.io/_uploads/BJCetlyd6.png" alt="iot_api_platform-1024x768" width="400" />
</div>
Network application programming interfaces (APIs) are protocols, routines, and tools used by software developers to build applications that can communicate over a network. Similarly, a network API enables communication between the network and applications, web browsers and databases. Network APIs can be used for either obtaining network information or providing configuration instructions. An API that uses representational state transfer (REST) architecture is often recognized as a RESTful API. These APIs are commonly used in networking. RESTful APIs use HTTP methods to gather and manipulate data, while HTTP uses RESTful APIs to interact with data.
### API For Telecommunication
Network APIs for telcos, also termed telecom APIs, facilitate the standardized interfaces between user-facing applications and complex 4G or 5G networks. These interfaces allow developers to access as well as control network resources and services such as low-latency connectivity and quality of service (QoS).Telecom APIs help developers to create cutting-edge applications and services that can enable advanced features on 4G networks, as well as implement low latency, ultra-fast data speeds and massive machine-type communication (mMTC) in the case of 5G.
### API Monetize Networks
Network APIs enable the development of revenue-generating applications on networks, such as through the implementation of the following examples:
1. **Network Slicing**: The utilization of network APIs facilitates the creation and management of network slices. These slices, formed through the deployment of network APIs, enable the operation of specific applications and services within virtual network segments.
2. **Low-latency Applications**: Software developers can leverage network APIs, such as Quality On Demand and device-specific APIs, to craft applications with minimal latency. This capability proves valuable in scenarios involving edge computing.
3. **mMTC/IoT Applications**: The application of device-specific Network APIs becomes instrumental in developing applications designed to interact with sensors and machines within Internet of Things (IoT) environments.
### Example Real API Usage
<div style="text-align:center;">
<img src="https://hackmd.io/_uploads/H1DahEl_T.png" alt="Database" width="500" />
</div>
The URI of an API comprises distinct elements:
1. **Connection Protocol**: It specifies the communication protocol, such as HTTP, HTTPS, or TCP, indicating how data will be transmitted.
2. **Host Name**: This segment includes the name of the hosting server, like Google or Facebook, identifying where the API is located.
3. **Endpoint Type**: It is sometimes beneficial to clarify whether the endpoint is an API endpoint or another type, aiding in endpoint categorization.
4. **Version**: Including a version in the API's design is essential for seamless updates. For instance, updating from V1 to V2 ensures that services relying on the API won't be disrupted when changes are made.
5. **Base Path**: Positioned after the version, the base path signifies the service's name that the client intends to access, forming a structured hierarchy.
6. **Query**: Following the base path, queries are appended using "?" instead of "/", enabling the passing of parameters for the endpoint. This allows for dynamic customization of requests, enhancing the flexibility of the API.
## DB [DataBase]
<div style="text-align:center;">
<img src="https://hackmd.io/_uploads/BkV1cxkOT.jpg" alt="Database" width="400" />
</div>
A database is an organized collection of information, used by organizations to store, maintain, and access data, aiding in informed business decisions. Databases improve business processes, track customer data, and help keep data secure through proper security measures like controlled access, encryption, and anonymization.
### Types of Databases
There are various types of databases :
1. **Relational Database**: Relational databases organize data into tables with rows and columns, using structured query language (SQL) for data manipulation and retrieval.
2. **Object-oriented Database**: Object-oriented databases store data as objects, encapsulating attributes and methods, allowing for a more seamless representation of real-world entities.
3. **Centralized Database**: Centralized databases store all data in a single location, facilitating easy management but posing a single point of failure.
4. **Distributed Database**: Distributed databases distribute data across multiple locations or servers, promoting scalability and fault tolerance.
5. **NoSQL Database**: NoSQL databases diverge from traditional relational models, allowing for flexible data structures and scalability in handling large volumes of unstructured data.
6. **Hierarchical Database**: Hierarchical databases organize data in a tree-like structure, with parent-child relationships between data elements.
7. **Network Database**: Network databases model data using a network structure, allowing for complex relationships between data entities through direct pointers.
8. **Cloud Database**: Cloud databases are hosted on cloud platforms, providing scalability, accessibility, and ease of management through cloud services.
### Correlation API and DB
<div style="text-align:center;">
<img src="https://hackmd.io/_uploads/S1Qqqeyup.png" alt="API and DB" width="600" />
</div>
Through a database API, developers can access and interact with a database, perform operations such as querying, inserting, updating, and deleting data. The API serves as an intermediary layer that abstracts the complexities of the database system, providing a standardized set of commands that developers can use to interact with the database. APIs and databases can also use create, read, update and delete (CRUD) functions to store and modify data. CRUD functions share similarities with HTTP functions, as seen here.
| CRUD Function | HTTP Function | Action | Use Case|
| -------- | -------- | -------- |--------|
| CREATE | POST | Configure a network remotely or Insert new records into a database | Adding a virtual LAN (VLAN) or Adding a new user to a user database |
| READ | GET | List network devices through telemetry or Retrieve data from a database | Listing devices in a network remotely or Fetching user information from a user database |
| UPDATE | PUT/PATCH | Modify a network config or Modify data in a database | Changing a VLAN's name or Updating a user's profile information |
| DELETE | DELETE | Delete unused VLANs or Remove records from a database | Deleting a VLAN or Deleting a user account from a user database |
## Networking Programming in this Area
<div style="text-align:center;">
<img src="https://hackmd.io/_uploads/BkdE84lOa.jpg" alt="API and DB" width="600" />
</div>
A network programming interface is a type of application programming interface (API) that comprises a set of communication routines or system calls. These routines can be invoked by an application to establish communication with another application, whether residing on the same or different computers.
In this context, the client and the database server are the specific applications utilizing the routines within the TLI or sockets API. Both clients and database servers employ network programming interfaces to transmit and receive data in accordance with a designated communications protocol.
To achieve successful communication between the client and the server, it is essential for both environments to be configured with the same protocol. Nevertheless, certain network protocols offer flexibility, allowing access through multiple network programming interfaces. For instance, TCP/IP can be accessed either through TLI or sockets, depending on the availability of the programming interface on the operating system platform
## Practice to Build API Server Connect DB
1. The first step in practicing the creation of an API connected to a database is to create the database itself. In this case, I am using the NoSQL MongoDB database, which is freely available.
<div style="text-align: center; margin-bottom: 50px;">
<img src="https://hackmd.io/_uploads/ryidwJXOT.png" alt="Mongo DB Home" width="600" />
</div>
2. After creating an account, the next step is to create a cluster, which will contain the database that will be used later.
<div style="text-align: center; margin-bottom: 50px;">
<img src="https://hackmd.io/_uploads/r1nzuJQda.png" alt="Mongo Database" width="600" />
</div>
3. Next, select the "Connect" menu, and you will obtain a connection string. This connection string is essential for establishing a connection from the server to the database. (Note : password is your credentials user access).
<div style="text-align: center; margin-bottom: 50px;">
<img src="https://hackmd.io/_uploads/SyrYuyXOT.png" alt="Mongo Database" width="600" />
</div>
4. Next, I will create a server based on Node.js to serve as the API server using the JavaScript programming language. For that purpose, the file structure is created as follows:
<div style="text-align: center; margin-bottom: 50px;">
<img src="https://hackmd.io/_uploads/BJy-YJQua.png" alt="Structure FIle" width="200" />
</div>
**5. For Detail package.json** :
```
{
"name": "simple_crud_api",
"version": "1.0.0",
"main": "server.js",
"scripts": {
"server": "nodemon server.js",
"start": "node server.js"
},
"dependencies": {
"body-parser": "^1.18.3",
"express": "^4.16.3",
"mongoose": "^5.13.22"
},
"devDependencies": {
"nodemon": "^1.18.10"
}
}
```
* **name**: This field specifies the name of your project.
* **version**: Indicates the version of your project.
* **main**: Specifies the entry point for your application. In this case, the main file is "server.js," meaning when someone runs your project, Node.js will start executing code from this file.
* **scripts**: This section defines custom scripts that can be executed using npm.
* **server**: Uses nodemon to run the "server.js" file. nodemon is a tool that helps in development by automatically restarting the server when changes are made to the source code.
* **start**: Directly runs the "server.js" file using node. This is typically used in a production environment where automatic restarts are not needed.
* **dependencies**: Lists the runtime dependencies for your project. These are packages that are required for your application to run.
* **"body-parser"**: Middleware for parsing incoming request bodies. Used to extract data from the request and make it available in req.body.
* **"express"**: A web application framework for Node.js. It simplifies the process of building robust web applications.
* **"mongoose"**: An ODM (Object Data Modeling) library for MongoDB and Node.js. It provides a straightforward way to interact with MongoDB databases.
* **devDependencies**: Lists dependencies that are only needed during development, not in a production environment.
* **"nodemon"**: A development dependency used for automatically restarting the server during development when changes are made. It's not necessary in production but greatly improves the development workflow.
**6. For Detail config/keys.js** :
```
module.exports = {
mongoURI: 'mongodb+srv://abdfikih:T0p3*ni*@cluster0.7cin9xq.mongodb.net/crud-api?retryWrites=true&w=majority'
};
```
The provided code exports a MongoDB connection URI from a Node.js module. This URI contains authentication details (username and password), cluster address, and database name. It is used by Mongoose to establish a connection with the specified MongoDB server for a CRUD API application.
**7. For Detail Models/person.js** :
```
const mongoose = require('mongoose');
const { Schema } = mongoose;
// Creating a new Schema for Person
const PersonSchema = new Schema({
// Here, we set the names of properties
name: {
// The type
type: String,
// And if is required or not
required: true
},
age: {
type: Number
},
date: {
type: Date,
default: Date.now
}
});
// Here, we export the model of persons
module.exports = mongoose.model('persons', PersonSchema);
```
The code defines a Mongoose schema for a "Person" in a MongoDB database. It uses the mongoose library to create a schema with properties such as "name," "age," and "date." Each property is defined with a type, and additional configurations, like whether the "name" is required or the default value for "date." The schema is then exported as a Mongoose model named 'persons,' indicating that it will interact with the 'persons' collection in the MongoDB database.
**8. For Detail Route/person.js** :
```
const express = require('express');
const router = express.Router();
const Person = require('../models/Person');
// @Route GET api/person/
// @desc Get all persons
// @access Public
router.get('/', (req, res) => {
// Sending html in response with message
res.send('Hello from persons');
// Query all documents in db
Person.find({}, (error, persons) => {
if (error) {
// Error handling
return res.status(500).json(error);
}
// Returning documents to client
return res.json(persons);
});
});
// @Route POST api/person/new
// @desc Creating a new person
// @access Public
router.post('/new', (req, res) => {
// Get name and age from body request
const { name, age } = req.body;
// Creating a new Person (Model)
const newPerson = new Person({
name,
age
});
// Saving the new Person in the db
newPerson
.save()
.then(person => res.json(person))
.catch(error => res.status(500).json(error));
});
// @Route PUT api/person/update/:id
// @desc Update a person
// @access Public
router.put('/update/:id', (req, res) => {
const { name, age } = req.body;
Person.findOneAndUpdate(
{ _id: { $eq: req.params.id } }, // Find one id equals to id in params
{ name, age }, // data to be updated
{ new: true } // to mongoose returns the updated document
)
.then(newPerson => {
return res.json(newPerson);
})
.catch(error => {
return res.status(500).json(error);
});
});
// @Route DELETE api/person/:id
// @desc Delete a person
// @access Public
router.delete('/:id', (req, res) => {
// Searching for a person and deleting
Person.findOneAndDelete({ _id: req.params.id })
.then(person => {
// If the id of person not exists, returns a error
if (!person) {
res.status(404).json({ msg: 'There is no user for this ID' });
}
return res.json(person);
})
.catch(error => {
// Handling the error
return res.status(500).json(error);
});
});
// Export the routes of person
module.exports = router;
```
Defines Express routes for a "Person" API, including functionality for retrieving all persons (GET /api/person/), creating a new person (POST /api/person/new), updating a person (PUT /api/person/update/:id), and deleting a person (DELETE /api/person/:id). The routes interact with a MongoDB database using Mongoose. The GET route retrieves all persons from the database, the POST route creates a new person, the PUT route updates an existing person, and the DELETE route removes a person based on the provided ID.
**9. For Detail server.js** :
```
// Import the packages
const express = require('express');
const mongoose = require('mongoose');
const bodyParser = require('body-parser');
// Create an instance for express
const app = express();
// Get the person routes
const person = require('./routes/person');
// Apply the bodyParser middleware, to get json data from requests (Body)
app.use(bodyParser.json());
// Apply the routes of /api/person
app.use('/api/person', person);
// Get the mongoURI for database
const db = require('./config/keys').mongoURI;
// Connecting with database
mongoose
.connect(db, { useNewUrlParser: true })
// If all run ok, console log the message
.then(() => console.log('MongoDB connected'))
// For console log any error
.catch(err => console.log(err));
// Port declaration
const port = process.env.PORT || 9000;
// Init the express.js server
app.listen(port, () => console.log(`Server running on ${port}`));
```
The server.js file serves as the main entry point for the Node.js application. It first imports necessary packages, such as Express for creating the web server, Mongoose for interacting with MongoDB, and Body-parser for parsing incoming JSON data. The script then creates an instance of the Express application, applies middleware to handle JSON data in requests, and sets up routes by including the person routes from the 'person.js' file. The application connects to the MongoDB database using the URI obtained from the 'keys.js' file in the 'config' directory. Finally, it specifies the port for the server to listen on, either using the environment variable PORT or defaulting to port 9000, and initializes the server, logging a message once the connection is established.
**10. Run Server** :
To run this server, start by installing the required packages using the command ```npm install``` in the terminal. This will generate the node_modules folder and package-lock.json file. Once the installation is complete, you can launch the server by entering the command ```npm run server``` in the terminal. This will start the Node.js server, allowing we to interact with the API endpoints defined in server. Like picture below :
<div style="text-align: center; margin-bottom: 10px;">
<img src="https://hackmd.io/_uploads/HyEZyl7d6.png" alt="Mongo Database" width="600" />
</div>
<div style="text-align: center; margin-bottom: 50px;">
<img src="https://hackmd.io/_uploads/Sy10JeXOa.png" alt="Mongo Database" width="600" />
</div>
11. Testing API :
In this test using Postman, where is a popular tool used for API development and testing, Server running at ```127.0.0.1:9000/api/person``` . API for the test :
* Creating a new person (POST /api/person/new)

* Retrieving all persons (GET /api/person/)

* Updating a person (PUT /api/person/update/:id)

* Deleting a person (DELETE /api/person/:id)

To verify that these APIs are usable and have a status code of 200, you can use testing tools like Postman or any HTTP client. Execute requests for each API endpoint and check the received HTTP status codes in the response. If the status codes are 200, it indicates that the requests were successful and the APIs are working as expected. APIs are considered usable and functional when they can successfully handle requests and provide appropriate responses with HTTP status code 200 and data in database always update.
* When create data in database :

* When delete data in database :

### Test API With Curl
Curl commands offer various options to customize and enhance HTTP requests. Here curl option we can use :
* -v (verbose): Provides detailed information about the request and response, including headers, status codes, and other debugging information. This is useful for gaining insights into the communication between the client and the server.
* -H (header): Allows users to include headers in the request. Headers can be specified to convey information such as content types or authentication tokens, influencing how the server processes the request.
* -D (write-out): Enables saving HTTP headers to a file. This option is beneficial for capturing and analyzing headers separately from the response body, aiding in detailed examination and debugging.
* -X (request): Specifies the HTTP method to be used in the request. Users can choose from various methods like GET, POST, PUT, DELETE, etc., depending on the desired interaction with the API.
* -d (data): Facilitates sending data payloads in the request body. Particularly useful for POST requests, this option allows users to include data parameters essential for the API to process and respond appropriately.
And more options in curl, you can explore with this command in your terminal ```curl --help all```. Here example for use Curl in this use case for API ```127.0.0.1:9000/api/person``` :
* Post Data

* Get Data

The headers in the response provide additional information about the server's handling of the HTTP request. Here is explanation :
* **X-Powered-By**: Express: This header indicates that the server is powered by the Express.js framework, revealing the technology used for server-side processing.
* **Content-Type**: application/json; charset=utf-8: The Content-Type header specifies that the content of the response is in JSON format, and the charset parameter indicates that the character encoding is UTF-8, ensuring proper interpretation of the textual data.
* **Content-Length**: 100: The Content-Length header specifies the length of the response body in bytes, helping the client to accurately read and process the received data.
* **ETag**: W/"64-tU2xDSxOloqdVsBNu/4s9WfQEfk": ETag is an entity tag that provides a unique identifier for the version of the resource. It can be used for caching and conditional requests, allowing clients to determine if the resource has been modified since a certain point in time.
* **Date**: Thu, 04 Jan 2024 15:04:43 GMT: The Date header indicates the timestamp when the response was generated by the server. It helps in tracking the timing of server responses.
* **Connection**: keep-alive: This header indicates that the connection between the client and the server is persistent (kept alive), which can improve the efficiency of subsequent requests by avoiding the overhead of establishing a new connection for each request.
* **Keep-Alive**: timeout=5: The Keep-Alive header provides additional information about the connection persistence, specifying a timeout value (in seconds) for how long the server is willing to keep the connection open in the absence of further requests from the client. In this case, the timeout is set to 5 seconds.