قالب وردپرس درنا توس
Home / Tips and Tricks / How do you build an API server? – CloudSavvy IT

How do you build an API server? – CloudSavvy IT



Express JS logo

API servers are everywhere – whenever you connect to or update a web application, your browser sends requests for the latest information. We take a look at how it is handled behind the scenes and how you can code your own API server.

What is an API server and how does it work?

Here is an example. You have a web application that needs to connect to a database and retrieve some data, such as posts from users on a social media site. You obviously cannot get users to connect directly to your database server, as it is a major security flaw that leaves connection information in your app.

The solution is to place a server in the middle that receives requests from the user, interprets them and then securely asks the database for the requested information. The user never has to see the database; in fact, it often runs in a private subnet to make it inaccessible to anything but your API servers.

This allows clients to access your data securely via HTTP / HTTPS. Because the API server is owned and controlled by you, that connection can be more easily secured. Even if you still need some form of authentication to verify that users are logged in as they say they are.

An API server installation

The API server is not intended to do heavy lifting on your site. For most static content, you want to use a traditional web server like NGINX, which will be much more efficient. For example, you will earn index.html and bundle.js with your NGINX server, which the client unpacks and runs. The client-side JavaScript application will then make a request to the API server that handles it from there.

You can create API servers with any language – all you need is the ability to listen to and respond to HTTP requests and the ability to connect to a database, both of which have many libraries for all languages. In this guide we use JavaScript with Node.JS and use Express for HTTP and route management. Another popular alternative with C # is ASP.NET from Microsoft.

If you are on AWS you may want to look at the AWS API GateWay. Instead of running a full API server, API GateWay offers an inexpensive managed solution that can serve as a front end for Lambda features and RDS.

Configure an API server with Express.JS

Express.JS is a web application framework that runs on Node (server-side JavaScript). It is very easy to use and fits well with JavaScript applications on the client side.

Create a new folder for the server and run npm init to set your package.json. Create App.jsand paste the following into:

const express = require('express')
const app = express()
const port = 3000

app.get("https://www.cloudsavvyit.com/", (req, res) => res.send('Message from Express route handler: Hello World!'))

app.listen(port, () => console.log(`Example app listening on port ${port}!`))

This is the basic tablet for a simple Express server. The server itself is created with express(). Routes and associated management functions are then registered. In this case, app.get("https://www.cloudsavvyit.com/", handler) registers a GET request handler on / route. There are other handler functions for the other HTTP verbs, such as POST and PUT.

In the driver, req the object represents the HTTP request, with res which represents the answer. Then res.send returns basic data, such as a string or JSON object. You can also use Express as a traditional web server with res.sendFile, but we recommend that you use a native for static object performance.

To start, you can run node App.js, men nodemon is better because it will monitor the base file for changes and restart automatically.

npm i -g nodemon

nodemon app.js

If you visit localhost:3000 in your browser, you should see explicitly responding to queries.

In addition to several management features, you can also match many different routes. Explicit routing is easy—app.get('/users') handles requests to /users. You can also match routes with wildcards and regular expressions. You can also stay router manager; for example, to create a new handler specifically for a subdirectory that '/users', which is separate from the main app and is usually stored and exported from its own file.

However, all this is still served via HTTP, so the first upgrade will be to configure HTTPS. This is easy to handle; all you need is your private SSL key and certificate. If you only test, you can create a self-signed certificate with openssl:

openssl req -nodes -new -x509 -keyout server.key -out server.cert

You’ll have to manually trust this certificate when Chrome freaks out, but it works. Rather than call listen app, we set up the HTTPS server, send the app, and then listen to it.

const express = require('express')
var https = require('https')
var fs = require('fs')

const app = express()
const port = 3000

app.get("https://www.cloudsavvyit.com/", (req, res) => res.send('Message from Express route handler: Hello World!'))

https.createServer({
    key: fs.readFileSync('server.key'),
    cert: fs.readFileSync('server.cert')
  }, app)
  .listen(port, () => console.log(`Example app listening on port ${port}!`))

Connect a database

This step depends on your specific database, but is really nothing special. All you need to do is install the Node.JS driver for your database, provide connection information to Express, and connect to it as you would with standard JavaScript (or any other language you use to build your API server).

For this guide, we use MongoDB, a JSON document database that is often linked to Express. If you have a Docker, you can run it in a container for testing:

docker run -d -p 27017-27019:27017-27019 --name mongodb mongo:4.0.4

You can use MongoDB Compass to connect to it and perform administrative tasks.

On the Express side of things, you need to install the MongoDB NPM package to connect to it.

npm install mongodb

Because we do not want Express to start until after the database is connected, we move app.listen() inside of MongoClient.connect().

const express = require('express')
var https = require('https')
var fs = require('fs')
const MongoClient = require('mongodb').MongoClient

const app = express()
const port = 3000

app.get("https://www.cloudsavvyit.com/", (req, res) => res.send('Message from Express route handler: Hello World!'))

var db;
MongoClient.connect('mongodb://localhost:27017/', (err, client) => {
  if (err) return console.log(err)
    db = client.db('test') // whatever your database name is

  https.createServer({
    key: fs.readFileSync('server.key'),
    cert: fs.readFileSync('server.cert')
  }, app)
  .listen(port, () => console.log(`Example app listening on port ${port}!`))
})

You can now connect to Mongo using db variable and all standard methods. You want to make sure to use async / await But otherwise you will return unprocessed promises.

app.get("https://www.cloudsavvyit.com/", async (req, res) => {
  const response = await db.collection('test').find().toArray();
  res.send(response)
})

This connects to the database, returns the contents of test collection and spit it out as a JSON array.

Since Express is only the front end for these functions, you do not need to define all your logic in this file – you can divide it into modules and import what you need to call from Express route managers.

Caching API requests for performance

Express is not the fastest. If you plan to use it in production, you will probably implement some form of caching so that it does not have to make expensive inquiries on repeatable requests.

One thing to note is that you should never cache anything that requires authentication to display, such as a user’s personal information. The general rule is that if the page is the same for everyone, you can cache it for everyone. The PUT, DELETE and POST methods should never be cached.

You can use a memory store like Redis for this, but a simple memory cache works pretty well. Install memory-cache from npm:

npm i memory-cache

Sedan i App.js, create a new cache intermediate before your routes:

const cache = require('memory-cache');

let memCache = new cache.Cache();
let cacheMiddleware = (duration) => {
  return (req, res, next) => {
    let key = '__express__' + req.originalUrl || req.url;
    let cacheContent = memCache.get(key);
    if(cacheContent){
      res.send( cacheContent );
      return;
    } else {
      res.sendResponse = res.send;
      res.send = (body) => {
        memCache.put(key,body,duration*1000);
        res.sendResponse(body);
      }
      next()
    }
  }
}

On the routes that you can cache, you can then use this intermediate before the primary handler to cache results for X seconds:

app.get('/products', cacheMiddleware(30), function(req, res){
  ...
});

Source link