Skip to content

Overrides

A generic backend is ok for very simple and straightforard flows, however chances are you are at some stage going to need to implement your own custom flow or business logic. Overrides exists exactly for that reason. They allow you to override the default handlers and add your custom logic to it

Example

In this example I have an app where the user can save favourite books. The user would also like to list the saved books and list them by a particular author. For this use case I will write two Overrides.

List books

typescript
import { Environment, Variables } from '@/context'
import { OverridesArgs as Args, SRI } from '@coderpunktech/codedraw-core'

export const MyBooks = async (args: Args<Environment, Variables>): Promise<Book[]> => {
  const sri: SRI.SRI = args.context.get('sri')
  const resourceManager = args.context.get('resourceManager')
  const accountId = args.context.get('jwtPayload')!.sub
  return await resourceManager.getCollection<Book>(sri).find({ saved_by: accountId })
}

In this first override I have created a function where I run a query to return all the books that have been saved by the logged in user. Now to wire it:

typescript
app.use('*', installSDK({
  /**
   * Configure your custom overrides here
   */
  overrides: {
    getRecord: {
      my_books: MyBooks,
    }
  },
}))

Now everytime I hit the following api /your-endpoint/api/record/book____my_books the above override will be invoked.

List books by author

typescript
import { Environment, Variables } from '@/context'
import { OverridesArgs as Args, SRI } from '@coderpunktech/codedraw-core'

export const BooksByAuthor = async (args: Args<Environment, Variables>): Promise<Book[]> => {
  const sri: SRI.SRI = args.context.get('sri')
  const authorId = sri.arguments!.get('author_id')!
  const resourceManager = args.context.get('resourceManager')
  return await resourceManager.getCollection<Book>(sri).find({ author_id: authorId })
}

In this second override I have created a function where I run a query to return all the books that have been written by a particular author. Now to wire it:

typescript
app.use('*', installSDK({
  /**
   * Configure your custom overrides here
   */
  overrides: {
    getRecord: {
      my_books: MyBooks,
      books_by_author: BooksByAuthor
    }
  },
}))

Now everytime I hit the following api /your-endpoint/api/record/book____books_by_author?author_id=123 the above override will be invoked.

Return a file in a Get Record override

typescript
import { Environment, Variables } from '@/context'
import { OverridesArgs as Args, SRI } from '@coderpunktech/codedraw-core'

export const   = async (args: Args<Environment, Variables>): Promise<{ data: File, __type: string, __contentType: string }> => {
  const blob: Blob = new Blob(['Hello!'], { type: 'text/plain' })
  const file = new File([blob], `hello.txt`, { type: 'text/plain' });

  return {
    data: file,
    __type: 'Blob',
    __contentType: 'text/plain',
  }
}

Get Record overrides support returning a response that's different than json. To achieve that once you created your file you have to return an object that includes the following fields:

  • data being the file that you want to return
  • __type with the value Blob
  • __contentType with your file content type value

The sdk is going to check for the __type field and when found and with a value of Blob it will return a response to the client with the contentType header set to the __contentType value.

Recap

An override can be use for custom data lookup/storage, custom flow or business logic, throwing errors see the error handler and anything you can fit in a function.