📄
API schema
Make an API schema lest you want others to literally have to conduct black box penetration testing to understand your API.
An API schema describes our API in a standardized way. API schemas can be validated, tested, and linted to ensure that they correspond to given standards. It's important to understand that in most cases the API schema is not the API itself.
You can either:
When you actually have a schema, make sure to make it accessible and visible (that's our reason for using Bump in the code part of this book).
There are a few ways to think about schemas, like "API design-first", in which we design the API and generate the actual code from the schema. Our way is more traditional since we create the code and keep the schema mostly as a representation of the implementation—However: A very important representation!
We use the OpenAPI 3 standard. The approach is a manually constructed representation of our actual behavior. This is hardly the most forward-looking option available, but it's easy to understand, easy to get right, and lets us (for what it's worth) implement the API as we need while trying to stay true to the schema specification.
🎯 Example: See
api/schema.yml
for the OpenAPI 3 schema. Since our approach is manual, we have to implement any security and/or validations on our end in code. In our case, this is both for in-going and outgoing data. Ingoing data can be seen handled at src/FakeUser/controllers/FakeUserController.ts
in checkInput()
, and outgoing data is handled in src/FakeUser/entities/User.ts
and its various validation functions like validateName()
.src/FakeUser/controllers/FakeUserController.ts
/**
* @description Check and validate input.
*/
function checkInput(event: APIGatewayProxyEvent): string {
const clientVersion =
event?.headers["X-Client-Version"] || event?.headers["x-client-version"];
const isClientVersionValid = validateClientVersion(clientVersion || "");
const userId = event?.requestContext?.authorizer?.principalId;
const isUserValid = validateUserId(userId || "");
if (!isClientVersionValid || !isUserValid)
throw new Error("Invalid client version or user!");
return clientVersion || "";
}
Note also that because this is intended as a public API, the OAS security object is not present.
For GraphQL, consider if something like Apollo Studio might be a way to cover this area for your needs.
Last modified 1yr ago