npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

@n7e/http

v0.6.1

Published

A library defining objects and procedures for working with the HTTP protocol.

Downloads

25

Readme

HTTP

A library defining objects and procedures for working with the HTTP protocol.

For further insights, read on.

Installation

To install this library use your favorite package manager. No additional steps are required to start using the library.

npm install @n7e/http

This library is implemented in TypeScript but can be used with JavaScript without any additional steps.

Messages

HTTP is a stateless request/response protocol that operates by exchanging messages across a reliable transport- or session-layer "connection". An HTTP "client" is a program that establishes a connection to a server for the purpose of sending one or more HTTP requests. An HTTP "server" is a program that accepts connections in order to service HTTP requests by sending HTTP responses.

Requests and responses has some properties in common, namely:

  • Protocol version
  • Header fields
  • Body

An HTTP message is represented by the Message interface, which is generic to the type extending it. This means that any methods on the Message interface returning the same instance will return a Message. Whilst methods on an extending interface will return instances of that same interface. This allows instances of Request and Response to return an instance of the same type when using inherited methods from the Message interface.

import { Message } from "@n7e/http";

const messageWithContentType: Message = message.withHeader("Content-Type", "text/plain");

Immutability

Messages are considered immutable and are implemented in such a way that any method that normally would mutate the instance produces a copy instead.

Given a GET request message:

request.method; // GET

When we call the withMethod method to "change" the request method a new request is produced leaving the existing request unchanged.

import { RequestMethod } from "@n7e/http";

const postRequest = request.withMethod(RequestMethod.POST);

request.method; // GET
postRequest.method; // POST

Request

A client sends an HTTP request to a server in the form of a request message, beginning with a request-line that includes a method, URI, and protocol version, followed by header fields containing request modifiers, client information, and representation metadata, an empty line to indicate the end of the header section, and finally a message body containing the payload body (if any).

Example request message:

GET /hello.txt HTTP/1.1
User-Agent: curl/7.16.3 libcurl/7.16.3 OpenSSL/0.9.7l zlib/1.2.3
Host: example.com
Accept-Language: en, mi

An HTTP request message is represented by the Request interface and inherits all methods from Message.

The Request interface extends Message interface in such a way that any inherited methods of the Message interface will return an instance of Request:

import { Request } from "@n7e/http";

const requestWithContentType: Request = request.withHeader("Content-Type", "text/plain");

Response

A server responds to a client's request by sending one or more HTTP response messages, each beginning with a status line that includes the protocol version, a success or error code, and textual reason phrase, possibly followed by header fields containing server information, resource metadata, and representation metadata, an empty line to indicate the end of the header section, and finally a message body containing the payload body (if any).

HTTP/1.1 200 OK
Date: Mon, 27 Jul 2009 12:28:53 GMT
Server: Apache
Last-Modified: Wed, 22 Jul 2009 19:15:56 GMT
ETag: "34aa387-d-1568eb00"
Accept-Ranges: bytes
Content-Length: 51
Vary: Accept-Encoding
Content-Type: text/plain

Hello World! My payload includes a trailing CRLF.

The Response interface extends Message interface in such a way that any inherited methods of the Message interface will return an instance of Response:

import { Response } from "@n7e/http";

const responseWithContentType: Response = response.withHeader("Content-Type", "text/plain");

URI

HTTP relies upon the Uniform Resource Identifier (URI) standard to indicate the target resource and relationships between resources.

A URI is represented by the Uri interface. The interface provides properties and methods to access and manipulate defined URI components.

URI Query Parser

Although there are a couple of common formats, since there's no specification for the URI query component format this library does not attempt to parse the URI query. It's up to the user to do this but this library provides an abstraction for parsing and formatting query components through the UriQueryParser interface.

import type { Uri, UriQueryParser } from "@n7e/http";

function someFunction(uri: Uri, queryParser: UriQueryParser): void {
    const parameters = queryParser.parse(uri.query ?? "");
    
    // ...
}

UriQueryParser is just an interface describing the functionality of a URI query parser. To create a URI query parser instance you need to reference a specific implementation.

Default Implementation

This library provides a default URI query parser implementation.

import { DefaultUriQueryParser } from "@n7e/http";

const queryParser = new DefaultUriQueryParser();

The expected and produced query format can be described as follows:

  • Key/value pairs are separated by a single &
  • Keys and values are separated by a single =
  • Multiple key values are represented by multiple identical keys
const parameters = queryParser.parse("key=value&anotherKey=another%20value&numbers=one&numbers=two");

// parameters -> Map(3) {
//     "key" => ["value"],
//     "anotherKey" => ["another value"],
//     "numbers" => ["one", "two"],
// }

Factories

To not only abstract the usage of HTTP related objects but also the creation of them this library provides a set of factory interfaces and associated default implementations. Using these interfaces allows the underlying implementations to be swapped out and can benefit testing greatly.

Request Factory

To create a request instance you should use a RequestFactory.

import { RequestFactory, RequestMethod } from "@n7e/http";

function someFunction(requestFactory: RequestFactory): void {
    const request = requestFactory.createRequest(RequestMethod.GET, "http://example.com");
    
    // ...
}

RequestFactory is just an interface describing the functionality of a request factory. To create a request factory instance you need to reference a specific implementation.

Default Implementation

This library provides a default implementation of RequestFactory. See the following example of how to create a request instance.

import { DefaultRequestFactory, DefaultUriFactory, RequestMethod } from "@n7e/http";

const requestFactory = new DefaultRequestFactory(new DefaultUriFactory());
const request = requestFactory.createRequest(RequestMethod.GET, "http://example.com");

Response Factory

To create a response instance you should use a ResponseFactory.

import { ResponseFactory, ResponseStatus } from "@n7e/http";

function someFunction(responseFactory: ResponseFactory): void {
    const response = responseFactory.createResponse(ResponseStatus.OK);
    
    // ...
}

ResponseFactory is just an interface describing the functionality of a response factory. To create a response factory instance you need to reference a specific implementation.

Default Implementation

This library provides a default implementation of ResponseFactory. See the following example of how to create a response instance.

import { DefaultResponseFactory, DefaultStreamFactory, ResponseStatus } from "@n7e/http";

const responseFactory = new DefaultResponseFactory(new DefaultStreamFactory());
const response = responseFactory.createResponse(ResponseStatus.OK);

URI Factory

To create a URI instance you should use a UriFactory.

import type { UriFactory } from "@n7e/http";

function someFunction(uriFactory: UriFactory): void {
    const uri = uriFactory.createUri("http://example.com");
    
    // ...
}

UriFactory is just an interface describing the functionality of a URI factory. To create a URI factory instance you need to reference a specific implementation.

Default Implementation

This library provides a default implementation of UriFactory. See the following example of how to create a URI instance.

import { DefaultUriFactory } from "@n7e/http";

const uriFactory = new DefaultUriFactory();
const uri = uriFactory.createUri("http://example.com");

Stream Factory

To create a stream instance you should use a StreamFactory.

import type { StreamFactory } from "@n7e/http";

function someFunction(streamFactory: StreamFactory): void {
    const stream = streamFactory.createStream("content");
    
    // ...
}

StreamFactory is just an interface describing the functionality of a stream factory. To create a stream factory instance you need to reference a specific implementation.

Default Implementation

This library provides a default implementation of StreamFactory. See the following example of how to create a stream instance.

import { DefaultStreamFactory } from "@n7e/http";

const streamFactory = new DefaultStreamFactory();
const stream = streamFactory.createStream("content");