Inspired by BulletProof React, I applied its codebase architecture concepts to the Twenty codebase.
This article focuses only on the API layer in Twenty codebase.
Prerequisite
Approach
The approach we take is simple:
Pick a route
Locate this route in Twenty codebase.
Review how the api layer is implemented.
We repeat this process for 3 pages to establish a common pattern, see if there’s any exceptions.
In this part 1.3, you will learn the API layer in the /create/profile route and see what library is used to create a profile, where these files are located.
I reviewed the /create/profile route and found that the following files give us a clear picture about API layer.
CreateProfile.tsx
CreateProfile is defined as shown below:
...
export const CreateProfile = () => {
...
const { updateOneRecord } = useUpdateOneRecord();
...
const onSubmit: SubmitHandler<Form> = useCallback(
async (data) => {
try {
if (!currentWorkspaceMember?.id) {
throw new Error('User is not logged in');
}
if (!data.firstName || !data.lastName) {
throw new Error('First name or last name is missing');
}
await updateOneRecord({
objectNameSingular: CoreObjectNameSingular.WorkspaceMember,
idToUpdate: currentWorkspaceMember?.id,
updateOneRecordInput: {
name: {
firstName: data.firstName,
lastName: data.lastName,
},
colorScheme: 'System',
},
});
setCurrentWorkspaceMember((current) => {
if (isDefined(current)) {
return {
...current,
name: {
firstName: data.firstName,
lastName: data.lastName,
},
colorScheme: 'System',
};
}
return current;
});
setCurrentUser((current) => {
if (isDefined(current)) {
return {
...current,
firstName: data.firstName,
lastName: data.lastName,
};
}
return current;
});
setNextOnboardingStatus();
} catch (error: any) {
enqueueErrorSnackBar({
apolloError: CombinedGraphQLErrors.is(error) ? error : undefined,
});
}
},
[
currentWorkspaceMember?.id,
setNextOnboardingStatus,
enqueueErrorSnackBar,
setCurrentWorkspaceMember,
setCurrentUser,
updateOneRecord,
],
);
}
There’s four things happening onSubmit.
updateOneRecord
setCurrentWorkspaceMember
setCurrentUser
setNextOnboardingStatus
updateOneRecord is from the following hook
import { useUpdateOneRecord } from '@/object-record/hooks/useUpdateOneRecord';
...
const { updateOneRecord } = useUpdateOneRecord();
useUpdateOneRecord.ts
useUpdateOneRecord.ts is a common hook used in the codebase to update a single record. This is evident from the below screenshot.
And this hook has 273 LOC a the time of writing this article.
This function’s declaration is as shown below:
const updateOneRecord = async <
UpdatedObjectRecord extends ObjectRecord = ObjectRecord,
>({
objectNameSingular,
idToUpdate,
updateOneRecordInput,
optimisticRecord,
recordGqlFields,
}: UpdateOneRecordArgs<UpdatedObjectRecord>) => {
This is a common function that takes objectNameSingular and id to perform update operations.
About me:
Hey, my name is Ramu Narasinga. Email: ramu.narasinga@gmail.com
Tired of AI slop?
I spent 3+ years studying OSS codebases and wrote 350+ articles on what makes them production-grade. I built an open source tool that reviews your PR against your existing codebase patterns.
Your codebase. Your patterns. Enforced.


Top comments (0)