Endpoint
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.
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>;
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({});
});
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
}
});
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
}
});
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);
});
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();
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();
Created by Elijah Cobb provided under the MIT license.
- Home
- Examples
- Creating an Endpoint
- Requests
- Responses
- Files
- Enforcing Types
- Endpoint Groups
- Creating a Server
- Using
HObject
- Error Handling
- Dynamic Endpoints
- Post Process Handler
Element is a group of developer tools I have built in TypeScript. Check them out at: element-ts.com.
Author: Elijah Cobb
NPM: @element-ts/hydrogen
Issue Reporting: Github Issues