Skip to content

Endpoint

Elijah Cobb edited this page Jan 16, 2020 · 9 revisions

About

An HEndpoint handles everything for every request. An endpoint answers requests with responses for a specific method on a specific endpoint. It has a handler, optional type, and an optional upload manager.

Instantiating

Although you can obviously create a new endpoint with the HEndpoint's constructor. I STRONGLY advice you just use the methods on an HEndpointGroup.

The methods available for you to create new endpoints are:

  • get(...)
  • post(...)
  • put(...)
  • delete(...)

They all follow the signature: get(endpoint: string, listener: HEndpointConstructorType | HEndpointHandler): void

You can either pass in an object or a handler when creating a new endpoint. If you pass in an object it must follow the types defined by HEndpointConstructorType. If you only need to specify a handler and don't care about the types or uploads requirements you can just provide a function that follows HEndpointHandler.

type HEndpointConstructorType = {
	handler: HEndpointHandler;
	types?: ObjectTypeDefinition;
	upload?: HUploadManagerConstructorType;
};

type HEndpointHandler = (req: HRequest, res: HResponse) => Promise<void>;

Basic

You can only use one send...() method but the following are all the ways you can provide a response.

endpointGroup.get("/endpoint", async(req: HRequest, res: HResponse): Promise<void> => {
res.send({msg: "Hello, world!"});
	res.sendString("Hello, world!");
	res.sendFile("/absolute-path-to-file");
	res.sendBuffer(Buffer.from("Hello, world!", "utf8"));
	res.sendStream(FS.createReadStream("/create-a-read-stream"));
	res.sendError(HError.init().msg("The error message").code(HErrorStatusCode.ImATeapot));
	res.err(HErrorStatusCode.ImATeapot, "The error message");
	res.sendHObject({});
});

Type Checking

If you need to do type checking you are going to have to use an object following HEndpointConstructorType when you create an endpoint. Type checking is provided by typit. If an incorrect type is provided a 400 - Bad Request will be sent to the client.

endpointGroup.get("/endpoint", {
	handler: async(req: HRequest, res: HResponse): Promise<void> => {
		res.sendString("Yay, you provided the right types!");
	},
	types: {
		foo: StandardType.NUMBER,
		bar: StandardType.STRING,
		isAlive: StandardType.BOOLEAN,
		nestedObjectsToo: new ObjectType({
			foo2: StandardType.STRING
		}),
		anyTypeIsOkHere: SpecialType.ANY,
		mustBeNULL: SpecialType.NULL
	}
});

Uploads

To have a file upload simply define a upload object that follows the HUploadManagerConstructorType type:

type HUploadManagerConstructorType = {
	location: HUploadManagerLocationType;
	extensions?: string[];
	sizeLimit?: number;
};

For the location you can either save the file in memory in the HRequest or you can stream it to the file system. You two options are HUploadManagerLocation.PAYLOAD or HUploadManagerLocation.STREAM. To access the data if you use STREAM you can call getPayloadStreamPath(): string | undefined on the HRequest. Do access the data if you use PAYLOAD you can call getPayload(): Buffer | undefined on the HRequest.

endpointGroup.post("/file-upload", {
	handler: async(req: HRequest, res: HResponse): Promise<void> => {

		const payload: Buffer | undefined = req.getPayload();
		const pathToStreamedData: string | undefined = req.getPayloadStreamPath();
		
		res.sendString(pathToStreamedData || "Oof, no file...");

	},
	upload: {
		sizeLimit: 5_000_000,
		extensions: ["jpeg", "jpg", "png"],
		location: HUploadManagerLocationType.Payload || HUploadManagerLocationType.Stream
	}
});

Downloads

To send a file you have a few options sendBuffer(), sendFile(), and sendStream(). Obviously only call one of these.

endpointGroup.post("/file-upload", async(req: HRequest, res: HResponse): Promise<void> => {

	const absoluteFilePath: string = "/absolute-path-to-file";

	res.sendBuffer(FS.readFileSync(absoluteFilePath));

	const options: HFileSendOptions = {
		type: HFileSendType.DOWNLOAD || HFileSendType.PREVIEW, // defaults to download
		name: "file-name.jpeg",
		mime: {type: "image", subtype: "jpeg"},
		length: 123456789, // will automatically be calculated for you if you don't define
	};

	res.sendFile(absoluteFilePath, options);
	res.sendStream(FS.createReadStream(absoluteFilePath), options);

});

Requests

A HRequest handles all incoming data from the client. View an entire page on HRequest.

const req: HRequest = ...
req.getHeaders();
req.getEndpoint();
req.getUrl();
req.getMethod();
req.getBody();
req.getPayload();

Responses

A HResponse handles all outgoing data to your client. View an entire page on HResponse.

const res: HResponse = ...
res.sendStream();
res.sendFile();
res.send();
res.sendBuffer();
res.sendString();
res.sendHObject();
res.sendError();
res.err();
res.error();