In order to encourage "Happy Path Programming" and make it easier for developers to validate request fully, the Acai comes with a host of built-in validations as well as the ability to extend with custom validations and middleware. See the full validation list here:
Examples
Don't like reading documentation? Then look at our examples, which can run locally!
This is not recommended for frequent use as it raises errors for every header which does not conform to the array provided. Many browsers, http tools, and libraries will automatically add headers to request, unbeknownst to the user. By using this setting, you will force every user of the endpoint to take extra care with the headers provided and may result in poor API consumer experience.
import{BaseEndpoint,Validate,Request,Response}from'acai-ts';exportclassMyEndpointextendsBaseEndpoint{@Validate({requiredBody:'post-grower-request'})asyncpost(request:Request,response:Response):Promise<Response>{// Body is validated against OpenAPI schemaconstgrower=request.body;response.body={message:'Grower created',grower};returnresponse;}}
import{BaseEndpoint,Validate,Request,Response}from'acai-ts';exportclassMyEndpointextendsBaseEndpoint{@Validate({requiredBody:'post-grower-request',response:{type:'object',required:['id','name'],properties:{id:{type:'string'},name:{type:'string'}}}})asyncpost(request:Request,response:Response):Promise<Response>{// Response will be validated against schemaresponse.body={id:'123',name:'John Doe'};returnresponse;}}
This will trigger the function you provided in the router config under the withAuth configuration
12345
exportconstrequirements={post:{auth:true}};
1 2 3 4 5 6 7 8 910
import{BaseEndpoint,Auth,Request,Response}from'acai-ts';exportclassMyEndpointextendsBaseEndpoint{@Auth()asyncpost(request:Request,response:Response):Promise<Response>{// Authentication is handled by router's withAuth middlewareresponse.body={message:'Authenticated request'};returnresponse;}}
import{Request,Response}from'acai-ts';import*asdbfrom'./logic/database';constcheckGrowerExists=async(request:Request,response:Response):Promise<void>=>{constresult=awaitdb.checkGrowerIdExists(request.pathParameters.id);if(!result){response.code=404;response.setError('grower',`grower with id: ${request.pathParameters.id} does not exist.`);}};exportconstrequirements={patch:{before:[checkGrowerExists]}};
1 2 3 4 5 6 7 8 910111213141516171819
import{BaseEndpoint,Before,Request,Response}from'acai-ts';import*asdbfrom'./logic/database';constcheckGrowerExists=async(request:Request,response:Response):Promise<void>=>{constresult=awaitdb.checkGrowerIdExists(request.pathParameters.id);if(!result){response.code=404;response.setError('grower',`grower with id: ${request.pathParameters.id} does not exist.`);}};exportclassMyEndpointextendsBaseEndpoint{@Before(checkGrowerExists)asyncpatch(request:Request,response:Response):Promise<Response>{// Pre-validation middleware runs firstresponse.body={message:'Grower exists and updated'};returnresponse;}}
Instead of getting a request and response as arguments passed to your API function, you will get an instance of the class you provided here (functional pattern only)
1 2 3 4 5 6 7 8 910111213
import{Grower}from'./logic/grower';exportconstrequirements={post:{dataClass:Grower}};// Handler receives Grower instance instead of requestexportconstpost=async(grower:Grower,response:Response):Promise<Response>=>{response.body={message:'Received grower instance',grower};returnresponse;};
1 2 3 4 5 6 7 8 910111213
// Note: dataClass is not supported with decorator pattern// Instead, use validation and manual class instantiationimport{BaseEndpoint,Validate,Request,Response}from'acai-ts';import{Grower}from'./logic/grower';exportclassMyEndpointextendsBaseEndpoint{@Validate({requiredBody:'GrowerSchema'})asyncpost(request:Request,response:Response):Promise<Response>{constgrower=newGrower(request.body);response.body={message:'Grower created',grower};returnresponse;}}
You can add as many custom requirements as you want, with any variable type you want, and they will be passed to your beforeAll, before, afterAll, after and withAuth middleware defined functions.