Appearance
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 valueBlob
__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.