This project is no longer being maintained. The successor project can be found here.
A support library designed to work with the yeoman
generator,
apifire-server
.
It takes an OpenAPI 3 spec, and generates routes, controllers, and validators for express in Typescript.
This library is a work-in-progress (alpha level, in my opinion), and works specifically with the author's use-cases.
It's been tested with the following files:
tests/openapi3/petstore.yaml
tests/openapi3/bt-example.yaml
tests/openapi3/spotlight-example.yaml
Notes:
- It is recommended that you use
Stoplight Studio
to design your OpenAPI spec- For a well-designed example using Stoplight Studio, see this OpenAPI definition
- For responses, only 200 responses are used with JSON response bodies.
- It is recommended to create an OpenAPI component type for request bodies and responses (aka Model in Stoplight Studio)
- Cookies / headers / auth definitions are not used
$ref
is supported in responses and parameters- Use
parameters
to define non-post body params, userequestBody
for body params - Content type
application/json
is only supported forrequestBody
and responses - Very basic
securitySchemes
support - only the firstsecurity
definition is used to protect an endpoint - Post / response bodies must be an object type. It cannot be an array. You can have properties that are of any type in that object, however.
This library is a fork of the openapi3-generator
project.
- Uses a custom
json-schema-ref-parser-alt
build that adds ax-original-ref
property as a reference to the original$ref
to the output schema, which is useful for static analysis when trying to generate types. - The templates that came with
openapi3-generator
were removed. - A new set of templates were added to work with
apifire-server
. - A prettifier was introduced to prettify the generated Typescript files.
To use it from the CLI:
npm install -g apifire
In the directory where the apifire-server
generated service is, run:
$ apifire api.yaml api-server
Where api.yaml
is the OpenAPI 3 spec file. You should always run this command whenever the spec
file changes.
This will generate the following structure:
/<service root>
├── src/
| ├── controllers-generated/
| | └── <operation>.ts
| ├── interfaces/
| | └── api.ts
| ├── routers/
| | ├── <operation>.router.ts
| | ├── validators/
| | | └── <operation>.validator.ts
In day-to-day usage, the controllers-generated/
directory contains the files that you may edit / pluck
to the service's controllers/
directory as you will implement your business logic in them.
The other directories and their files should never be modified.
Usage: apifire [options] <openapiFileOrURL> <template>
Options:
-V, --version output the version number
-o, --output <outputDir> directory where to put the generated files (defaults to current directory)
-t, --templates <templateDir> directory where templates are located (defaults to internal templates directory)
-b, --basedir <baseDir> directory to use as the base when resolving local file references (defaults to OpenAPI file directory)
-h, --help output usage information
Stoplight Studio is a recommended way to design your OpenAPI spec.
The following items were generated using the tests/openapi3/stoplight-example.yaml
file.
export interface CreateAccountParams {
/**
* Account email
*/
email: string
/**
* Hashed password
*/
passHash: string
/**
* Authentication type
*/
authType: string
/**
* Code to verify account
*/
verifyCode: string
/**
* Account id in path
*/
pAccountId: string
}
export interface CreateAccountResponse {
status?: number
/**
* Created account id
*/
id?: string
}
/**
* Creates a new account
*/
router.post(
'/:pAccountId',
async (req: IRequest, res: Response, next: NextFunction) => {
const params: ApiInterfaces.CreateAccountParams = {
pAccountId: (req.params.pAccountId as unknown) as string,
email: (req.body.email as unknown) as string,
passHash: (req.body.passHash as unknown) as string,
authType: (req.body.authType as unknown) as string,
verifyCode: (req.body.verifyCode as unknown) as string
}
try {
validateCreateAccountParams(params)
const result = await createAccount(req.context, params)
res.status(result.status || 200)
delete result.status
res.send(result)
} catch (err) {
next(err)
}
}
)
apifire
generates validators that validate the incoming request parameters.
const createAccountValidator = ajv.compile({
type: 'object',
required: ['pAccountId', 'email', 'passHash', 'authType', 'verifyCode'],
properties: {
pAccountId: { type: 'string' },
email: {
type: 'string',
},
passHash: {
type: 'string',
},
authType: {
type: 'string',
},
verifyCode: {
type: 'string',
}
}
})
export function validateCreateAccountParams (params) {
const valid = createAccountValidator(params)
if (!valid) {
throw getErrRegistry()
.newError('VALIDATION_FAILURE', 'INVALID_REQ_PARAMS')
.withSafeMetadata({
validations: createAccountValidator.errors
})
}
}
You fill in your business logic in a controller, which is called by the router.
/**
* @param {IRequestContext} context
* @param {Object} params
* @throws {Error}
* @return {Promise}
*/
export async function createAccount (
context: IRequestContext,
params: ApiInterfaces.CreateAccountParams
): Promise<ApiInterfaces.CreateAccountResponse> {
return {
id: ''
}
}
- Theo Gravity (github)
- Fran Méndez (@fmvilas)
- Richard Klose (@richardklose)