Friends Of AdonisFriends Of Adonis

Generic types

Generic types allows you to reduce code duplication. For example, if all your index endpoints return paginated responses it wouldn't be productive to write again and again the same class for each of your models.

Hopefully we can leverage mixins to avoid this.

import { ,  } from '@foadonis/openapi/decorators'
 
function < extends object>(: new (...: any[]) => ) {
  abstract class  {
    @()
    declare : number
 
    @({ : [] })
    declare : []
  }
}
 
class  extends (Recipe) {}
 
class  {
  @({ :  })
  () {
    // ...
  }
}

Examples

Lucid Paginated response

In the following example we will create a mixin to create schemas for Lucid pagination.

app/controllers/users_controller.ts
import {  } from '@adonisjs/core/http'
import {  } from '@foadonis/openapi/decorators'
import  from '#models/user'
 
export class  {
  @({ : 'page' })
  @({ : 'limit' })
  ({  }: ) {
    const  = .('page', 1)
    const  = .('limit', 25)
    return .query().paginate(, )
  }
}

Meta schema

First we will need to create the schema for the meta property of our PaginatedResponse.

app/openapi/schemas/paginated_response.ts
import {  } from '@foadonis/openapi/decorators'
 
export class  {
  @()
  declare : number
 
  @()
  declare : number
 
  @()
  declare : number
 
  @()
  declare : number
 
  @()
  declare : number
 
  @()
  declare : string
 
  @()
  declare : string
 
  @({ : false })
  declare ?: string
 
  @({ : false })
  declare ?: string
}

Mixin

We can now create a mixin that will have the properties data and meta.

app/openapi/schemas/paginated_response.ts
import {  } from '@foadonis/openapi/decorators'
 
export default function < extends object>(
  : new (...: any[]) => 
) {
  abstract class  {
    @()
    declare : 
 
    @({ : [] })
    declare : []
  }
}

Usage

You can now use the mixin in your controllers and simply pass the User model as a parameter.

app/controllers/users_controller.ts
import {  } from '@adonisjs/core/http'
import { ,  } from '@foadonis/openapi/decorators'
import  from '#models/user'
import  from '#openapi/schemas/paginated_response'
 
class  extends () {} 
 
export class  {
  @({ : 'page' })
  @({ : 'limit' })
  @({ :  }) 
  ({  }: ) {
    const  = .('page', 1)
    const  = .('limit', 25)
    return .query().paginate(, )
  }
}

On this page