Categories
Koa Nodejs

Validating Request Data with Koa

Koa is a small framework that lets us create backend apps that run on the Node.js platform.

In this article, we’ll look at how to validate request data type with Koa.

Validating Request Data Type Using the request.is Method

We can call the ctx.is method with the string for the data type that we’re checking for to check if the data type from the Content-Type header’s value matches what we have in the argument.

It can take one or more data types. For instance, we can use it as follows:

const Koa = require('koa');
const app = new Koa();

app.use(async (ctx, next) => {
  if (ctx.is('text/*', 'text/html')){
    ctx.body = 'valid';
  }
  else {
    ctx.body = 'invalid';
  }
});

app.listen(3000);

In the code above, we called the ctx.is method with the strings for 2 data types, which are ‘text/*’ and ‘text/html’ to check if the incoming request have any of these values as the value of its Content-Type header.

If one of these values are includes, then it returns 'valid' as the response body.

Otherwise, it returns 'invalid' .

Content Negotiation

Content Negotiation is a mechanism that’s used to serve different representations of a resource from the same URL. We can use the user agent that can specify which is best suited for the user.

When making requests to the client, we can use the Accept , Accept-Charset , Accept-Encoding , or Accept-Language headers in the request to let the server know what kind of data the client accepts.

With that data, the server can return a response with the most suitable kind of data for the client.

For instance, we can use it as follows:

const Koa = require('koa');
const app = new Koa();

app.use(async (ctx, next) => {
  if (ctx.accepts('html')){
    ctx.body = 'accepts html';
  }
  else if (ctx.accepts('application/json')){
    ctx.body = 'accepts json';
  }
  else if (ctx.accepts('image/png')){
    ctx.body = 'accepts png';
  }
  else {
    ctx.body = 'accepts everything';
  }
});

app.listen(3000);

In the code above, we called the ctx.accepts method with the content-type string that we want to check for in those headers listed above, so that we can return the appropriate response for it.

Then when we make a request to our app with one of those headers and application/json as its value, then we get the string 'accepts json' returned as the response.

Checking for the Encoding that the Client Accepts

We can use the ctx.acceptsEncodings method to check what kind of encoding the client accepts.

It takes one more encoding type strings as its argument or it can be one array of encoding type strings.

For instance, we can use it as follows:

const Koa = require('koa');
const app = new Koa();

app.use(async (ctx, next) => {
  if (ctx.acceptsEncodings('gzip') === "gzip"){
    ctx.body = 'accepts gzip';
  }
  else {
    ctx.body = 'does not accept gzip';
  }

});

app.listen(3000);

In the code above, we called the ctx.acceptEncodings method with the argument 'gzip' . The method returns the encoding that’s the best match.

Then if we make a request to our app with the Accept-Encoding header gzip, deflate, br , we’ll get that the response 'accepts gzip' from the app.

If no arguments are given, then all accepted encodings are returned.

Checking the Character Set That’s Accepted By the Client

We can call the acceptsCharsets to check for the character sets that are accepted by the client.

It also takes one or more string for the character set names that are accepted or an array of strings with those character set names.

For instance, we can use it as follows:

const Koa = require('koa');
const app = new Koa();

app.use(async (ctx, next) => {

  if (ctx.acceptsCharsets('utf-8') === 'utf-8'){
    ctx.body = 'accepts utf-8';
  }
  else {
    ctx.body = 'does not accept utf-8';
  }

});

app.listen(3000);

The code above is similar to the acceptEncodings code.

If we make a request that doesn’t include the Accept-Charset header that includes utf-8 , then we’ll get ‘does not accept utf-8’ returned as the response.

Otherwise, we’ll get 'accepts utf-8' returned whether we made the request explicitly with the Accept-Charset header with utf-8 as the value or not.

Checking the Language of the Request

The ctx.acceptsLanguages let us check the language of the request according to the Accept-Language header.

It’s similar to the other 2 methods above with the arguments that it takes and what it returns.

Get Any Header Field

We can get any request header field with the ctx.get method. For instance, we can write the following to do that:

const Koa = require('koa');
const app = new Koa();

app.use(async (ctx, next) => {
  ctx.body = ctx.get('foo');
});

app.listen(3000);

In the code above, we called the get method with the 'foo' header name. It returns the value of the 'foo' header if it exists.

Then when we make a request with the foo header with value bar , we’ll see 'bar' returned as the response.

Conclusion

We can use the ctx.is method to validate data types that are sent to the server.

To do content negotiation, we can use the accepts method. To check the language, encoding, or character set, there’re methods to do that.

Finally, we can get any request header value with the get method.

Categories
Koa Nodejs

Getting Request Data with Koa

Koa is a small framework that lets us create backend apps that run on the Node.js platform.

In this article, we’ll look at how to receive request data with Koa.

Getting the Content-Type Header of a Request

We can use the ctx.request.type property to get the Content-Type header of the request.

For instance, we can write the following code to display the value of that on the screen:

const Koa = require('koa');
const app = new Koa();

app.use(async (ctx, next) => {
  ctx.body = ctx.request.type;
});

app.listen(3000);

Then if we send our request with the Content-Type header’s value set to application/json , then we’ll get that displayed on the screen when we get the response.

Get the Character Set of the Request

The ctx.request.charset property has the request character set.

Getting the Query String From a Request URL

The ctx.request.query property has query string parsed into a key-value pair.

Each query parameter of the query string is parsed into a key-value pair of an object.

For instance, we can use it as follows:

const Koa = require('koa');
const app = new Koa();

app.use(async (ctx, next) => {
  ctx.body = ctx.request.query;
});

app.listen(3000);

In the code above, we just set the query property as the value of the ctx.body .

Then when we make a request to https://CraftyGrouchyCables–five-nine.repl.co?a=1&b=2, we get the following response:

{
    "a": "1",
    "b": "2"
}

As we can see, the key-value pairs from the query string are parsed as the key-value pairs of the object set as the value of ctx.request.query without doing anything ourselves.

The ctx.request.query property is also a setter, so we can set it to something else. However, it doesn’t support nested objects.

Check if the Request Cache is Fresh, or if its Content Has Changed or Not

We can check the request cache’s freshness by using the ctx.fresh property.

For instance, we can use it as follows:

const Koa = require('koa');
const app = new Koa();

app.use(async (ctx, next) => {
  ctx.status = 200;
  ctx.set('ETag', 'foo');
  if (ctx.fresh) {
    ctx.status = 304;
    console.log('fresh');
    return;
  }
  ctx.body = 'foo';
});

app.listen(3000);

In the code above, we check if the request cache is fresh by using the ctx.fresg property. If it’s fresh, then we’ll see the fresh string logged.

Otherwise, we won’t see it logged. If we make more than one request to our app, then we won’t see it logged since the cache has been populated with data that haven’t change we always return the same response.

There’s also a ctx.stale property to check that the opposite status of ctx.fresh is true .

Get the Protocol of Our Request

We can use the ctx.request.protocol property to get the request protocol. It’s either https or http .

If app.proxy is set to true , it can also check the X-Forwarded-Proto request header for the protocol.

Get the IP Address of the Device Making the Request

The ctx.request.ip and ctx.request.ips can get us the remote address of the device making the request.

The ips property gets us the IP address of all the devices that the request went through to make it to our app.

For instance, we can use the ip property as follows:

const Koa = require('koa');
const app = new Koa();

app.use(async (ctx, next) => {
  ctx.body = ctx.request.ip;
});

app.listen(3000);

Then when we make a request to our app, we get the IP address of the device that made the request.

We can also use the ips property if app.proxy is set to true . For instance, we can use it as follows:

const Koa = require('koa');
const app = new Koa();

app.proxy = true;

app.use(async (ctx, next) => {
  ctx.body = ctx.request.ips;
});

app.listen(3000);

Then we’ll see an array of IP addresses that the request went through to reach our Koa app.

Photo by Carles Rabada on Unsplash

Get the Request Subdomains

We can get the subdomains of the request URL by using the subdomain property.

For example, we can use that as follows:

const Koa = require('koa');
const app = new Koa();

app.use(async (ctx, next) => {
  ctx.body = ctx.request.subdomains;
});

app.listen(3000);

Then if our app lived in https://CraftyGrouchyCables–five-nine.repl.co, we get that the subdomains property will return [“craftygrouchycables — five-nine”] so we’ll get that displayed on the screen as the response value.

Conclusion

We can use the ctx.request property to get the IPs and the subdomains of the requested URL.

The protocol and query string are also available. Query strings are automatically parsed into an object.

Categories
Koa Nodejs

Sending Response with Koa

Koa is a small framework that lets us create backend apps that run on the Node.hs platform.

In this article, we’ll look at how to send various kinds of responses with Koa.

Sending the Body

To send the response body, we can set the body attribute of ctx . For instance, we can send a response body as follows:

const Koa = require('koa');
const app = new Koa();

app.use(async (ctx, next) => {
  ctx.body = 'foo';
});

app.listen(3000);

In the code above, we set the ctx.body property to 'foo' . Therefore, that’s what we’ll get when we go to the / route with our browser or make a request to it with an HTTP client.

Sending Response Header

We can send responses in our Koa code by setting the ctx.response property.

To set the header, we can set the response header with the ctx.set method.

For instance, we can use it as follows:

const Koa = require('koa');
const app = new Koa();

app.use(async (ctx, next) => {
  ctx.set('Access-Control-Allow-Origin', '*');
  ctx.set('Access-Control-Allow-Headers', 'Origin, X-Requested-With, Content-Type, Accept');
  ctx.set('Access-Control-Allow-Methods', 'POST, GET, PUT, DELETE, OPTIONS');
  ctx.body = 'hello';
});

app.listen(3000);

In the code above, we called ctx.set to set various headers, including the Access-Control-Allow-Origin header, Access-Control-Allow-Headers header, and Access-Control-Allow-Methods header.

Once we make a request to / , we’ll see those headers in HTTP clients like Chrome or Postman.

Sending Response Status Code

We can send response status codes by setting the status code value to the responbse.status property.

For instance, we can do that as follows:

const Koa = require('koa');
const app = new Koa();

app.use(async (ctx, next) => {
  ctx.status = 202;
  ctx.body = 'accepted';
});

app.listen(3000);

In the code above, we set the ctx.status ‘s value to 202. So when we make a request to the / route, we’ll get the 202 status code from the request.

Some common response codes that are send include:

  • 200 — OK
  • 201 — created
  • 202 — accepted
  • 203 — non-authoritative information
  • 204 — no content
  • 301 — move permanently
  • 302 — found
  • 303 — see other
  • 307 — temporary redirect
  • 308 — permanent redirect
  • 400 — bad request
  • 401 — unauthorized
  • 403 — forbidden
  • 404 — not found
  • 405 — method not allowed
  • 406 — not acceptable
  • 422 — unprocessable entity
  • 500 — internal server error
  • 501 — not implemented
  • 502 — bad gateway
  • 504 — gateway timeout

Sending Headers

We can set the ctx.response.lastModified property to the date value that we want.

For instance, we can set that as follows:

const Koa = require('koa');
const app = new Koa();

app.use(async (ctx, next) => {
  ctx.response.lastModified = new Date(2020, 0, 1);
  ctx.body = 'foo';
});

app.listen(3000);

In the code above, we set the lastModified property to January 1, 2020, so when we make the request to the / route, we’ll get the Last-Modified from the response with the value of Wed, 01 Jan 2020 00:00:00 GMT .

We can set the Content-Type response header by writing setting the ctx.type property. For instance, we can do that as follows:

const Koa = require('koa');
const app = new Koa();

app.use(async (ctx, next) => {
  ctx.type = 'text/plain; charset=utf-8';
  ctx.body = 'foo';
});

app.listen(3000);

In the code above, we have the following code:

ctx.type = 'text/plain; charset=utf-8';

to set the Content-Type header to ‘text/plain; charset=utf-8’ . Then we’ll see that as the value of the Content-Type header when we make the request to the / route.

To append one more header to the response, we can call the ctx.append to append more headers. It takes the key and value as its 2 arguments.

For instance, we can use it as follows:

const Koa = require('koa');
const app = new Koa();

app.use(async (ctx, next) => {
  ctx.append('a', 1);
  ctx.body = 'foo';
});

app.listen(3000);

In the code above, we called the ctx.append method with the header key 'a' and the corresponding value of 1.

Then when we make a request to the / route, we’ll get the response header A with the value 1 appearing.

Conclusion

We can set response headers by calling the ctx.append method. To return a response body, we can set the ctx.body property with a value.

To set the status code of the response, we set the ctx.status property.

Categories
Koa Nodejs

Receiving Requests with Koa

Koa is a small framework that lets us create backend apps that run on the Node.js platform.

In this article, we’ll look at how to receive request data with Koa.

Receiving Headers

We can get the request headers of a request by using the ctx.request.header property.

For instance, we can get the headers as follows:

const Koa = require('koa');
const app = new Koa();

app.use(async (ctx, next) => {
  ctx.body = ctx.request.headers;
});

app.listen(3000);

In the code above, we just assigned the ctx.request.headers object as the value of ctx.body so that we’ll see the request headers as the response body.

Then we should see something like the following when we make a request to the / route:

{
    "host": "craftygrouchycables--five-nine.repl.co",
    "user-agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.122 Safari/537.36 Edg/80.0.361.62",
    "content-length": "90",
    "accept": "*/*",
    "accept-encoding": "gzip, deflate, br",
    "cache-control": "no-cache",
    "content-type": "application/json",
    "postman-token": "fd561c8c-6419-4939-87f5-dc989d5b9845",
    "x-forwarded-for": "35.191.2.193",
    "x-replit-user-id": "",
    "x-replit-user-name": "",
    "x-replit-user-roles": ""
}

We can also set the request.header to set the request header.

Its alias is request.headers . They get and set the same data.

Getting the Request Method from a Request

We can use the ctx.request.method to get the request method of the request.

For instance, we can display it on the screen by writing the following code:

const Koa = require('koa');
const app = new Koa();

app.use(async (ctx, next) => {
  ctx.body = ctx.request.method;
});

app.listen(3000);

Like with the request.header property, we set the ctx.request.method as the value of ctx.body , then we see GET displayed on the screen if we make a GET request to the / route.

Get the Value of the Content-Length Request Header

We use the ctx.request.length to get the value of the Content-Length request header. If it’s present, it’ll return the value. Otherwise, undefined is returned.

Get the URL of the That’s Requested

The ctx.request.url property has the URL that’s requested by the HTTP request to our app.

We can display it as follows:

const Koa = require('koa');
const app = new Koa();

app.use(async (ctx, next) => {
  ctx.body = ctx.request.url;
});

app.listen(3000);

We just set the url property to the ctx.body to return it as the response body. If we make a request to the / route, then we get / displayed.

It can also be used as a setter. Therefore, it makes this property handy for doing URL rewrites. For instance, we can rewrite requests to /foo and rewrite them to / by writing the following code:

const Koa = require('koa');
const app = new Koa();

app.use(async (ctx, next) => {
  if (ctx.request.url.includes('/foo')){
    ctx.request.url = '/';
  }
  ctx.body = ctx.request.url;
});

app.listen(3000);

In the code above, we checked that if our request URL includes the /foo segment. If it does, then we change it to / .

Therefore, when we make a request to / or /foo , we’ll see / displayed on the screen.

Photo by Max Letek on Unsplash

Get the Original URL of the Request

We can use the ctx.request.originalUrl property to get the original request URL. It’ll be a relative URL. So if we make a request to /foo to a Koa app that has the following code:

const Koa = require('koa');
const app = new Koa();

app.use(async (ctx, next) => {
  ctx.body = ctx.request.originalUrl;
});

app.listen(3000);

We’ll see that /foo is displayed.

If we want to include the protocol and host of the server in the URL, then we can use the ctx.request.origin property instead.

For instance, we can write the following code:

const Koa = require('koa');
const app = new Koa();

app.use(async (ctx, next) => {
  ctx.body = ctx.request.origin
});

app.listen(3000);

Then we get the protocol and hostname of the server that our app resides in.

If we want to get the full URL, then we can use the ctx.request.href property.

For instance, we can write the following code:

const Koa = require('koa');
const app = new Koa();

app.use(async (ctx, next) => {
  ctx.body = ctx.request.href;
});

app.listen(3000);

Then when we make a request to https://CraftyGrouchyCables–five-nine.repl.co/foo, we get back the whole URL on the screen if we have the code above.

Conclusion

We can get various pieces of data from a URL with the request property of the ctx context object. It has the header, request URL, request method and more.

Categories
Koa Nodejs

Using Middlewares with Koa

Koa is a small framework that lets us create backend apps that run on the Node.hs platform.

In this article, we’ll look at how to create our Koa app with our own middlewares.

Middleware is a Building Block of a Koa App

Koa apps are made up of middlewares. We can define and use it by writing the following code:

const Koa = require('koa');
const app = new Koa();

app.use(async (ctx, next) => {
  ctx.body = 'foo';
});

app.listen(3000);

In the code above, the async function is our middleware. In the function, we just set the body to 'foo' so that we can see that displayed on the screen if we opening our browser.

Cascading Middleware

We can chain more than one middlewares together with the next function, which is available from the parameter of the middleware function. It’s the 2nd parameter.

For instance, we can call it as follows:

const Koa = require('koa');
const app = new Koa();

app.use(async (ctx, next) => {
  const start = Date.now();
  await next();
  const ms = Date.now() - start;
  ctx.set('X-Response-Time', ms);
});

app.use(async (ctx, next) => {
  ctx.body = 'Hello';
});

app.listen(3000);

In the code above, we have 2 middlewares, which we call one by one with passing each one to their own app.use call.

In the first middleware, we set the X-Response-Time response header by setting the ms constant to the current time minus the start time.

To call the 2nd middleware, we call the next function from the 2nd parameter of the middleware function.

In the second middleware, we set the response body of our route by setting ctx.body to 'Hello' .

Therefore, when we make a request to the / route, we get that the body is ‘Hello’ and one of the response headers is X-Response-Time with the number of milliseconds to process the request after the request is made.

Error Handling

We use error handling to catch errors and handle them. To listen to error events and handle them, we call the app.on method to catch the error.

For instance, we can handle errors as follows:

const Koa = require('koa');
const app = new Koa();

app.use(async (ctx, next) => {
  try {
    await Promise.reject('error');
  } catch (err) {
    ctx.status = err.status || 500;
    ctx.body = err.message;
    ctx.app.emit('error', err, ctx);
  }
});

app.on('error', (err, ctx) => {
  console.log(err);
});

app.listen(3000);

In the code above, we have a try...catch block to catch any errors that are thrown, which it’s the case since we have Promise.reject .

Then we called ctx.app.emit to emit the error event, which sends the err object that has the rejection reason from the promise, along with the ctx context object.

Then in the error handler that’s passed in as the 2nd argument as the app.on method call, we log the error.

Now when we make a request to the / route, we see that 'error' is logged in the console.

Using ctx.throw

The ctx.throw method lets us throw an error in our app. It takes the response code as the first argument and the error message as the 2nd argument.

For instance, we can use it as follows:

const Koa = require('koa');
const app = new Koa();

app.use(async (ctx, next) => {
  ctx.throw(500, 'error');
});

app.on('error', (err, ctx) => {
  console.log(err);
});

app.listen(3000);

In the code above, we called the ctx.throw method with the error 500 and the error message 'error' .

The error message will be available within the callback that we passed into the app.on method. The error message will be available as the value of the message property.

Using ctx.assert

Koa’s context object also has the ctx.assert method that throws an error if the condition isn’t met. The condition is passed into the first argument of the method. The 2nd argument is the response code that we want to send if the condition isn’t met.

For instance, we can use it as follows:

const Koa = require('koa');
const app = new Koa();

app.use(async (ctx, next) => {
  ctx.assert(ctx.request.accepts('json'), 406);
  ctx.body = 'hello';
});

app.on('error', (err, ctx) => {
  console.log(err);
});

app.listen(3000);

In the code above, we have called the ctx.assert method as follows:

ctx.assert(ctx.request.accepts('json'), 406);

Now if our request header has the Accept request header that’s like the following:

application/json

Then we’ll get hello’ displayed on the screen.

Otherwise, if our request Accept header is application/atom+xml , then we’ll get the back a 406 response.

Conclusion

With Koa middlewares, we can build simple apps by writing one or more middleware. If we have more than one middleware, then we can chain them together by calling the next function that’s available from the parameter of the middleware function.

We also use middlewares to handle errors. However, instead of passing them to the app.use method, we pass them into the app.on method.

Then we can use methods like ctx.assert and ctx.throw to throw errors, then the error gets sent to the error handler automatically.

If you like the content of this blog, subscribe to my email list to get exclusive articles not available to anyone else.