AI Skill Report Card
Building TypeScript API Controllers
Quick Start15 / 15
TypeScriptexport const getResourceController = async ( id: string, qsParams: ResourceQueryParams, ): Promise<AxiosResponse<App.Pagination<Resource>, any>> => { const url = `/api/resource/${id}`; const instance = genRequestInstance(); try { const response = await instance.get(url, { params: qsParams }); return response; } catch (error) { console.error('Erro na requisição:', error); return Promise.reject(error); } };
Recommendation▾
Remove the generic 'Builds TypeScript API controller functions' opening and jump straight to the pattern/methodology
Workflow12 / 15
Progress:
- Define function signature with URL parameters first, then query string params
- Build URL path with required parameters embedded
- Create request instance
- Make request with query string as
paramsobject - Handle errors with console.error and Promise.reject
Step-by-step Process:
- Function signature: Required URL params first, then optional query string params
- URL construction: Embed required parameters directly in URL path
- Query string handling: Always use
{ params: qsParams }pattern - Error handling: Log error and reject promise
Recommendation▾
Expand the workflow checklist to include type definitions for QueryParams interfaces and return type patterns
Examples20 / 20
Example 1: With URL parameter
TypeScriptexport const getUserPostsController = async ( userId: string, qsParams: PostQueryParams, ): Promise<AxiosResponse<App.Pagination<Post>, any>> => { const url = `/api/user/${userId}/posts`; const instance = genRequestInstance(); try { const response = await instance.get(url, { params: qsParams }); return response; } catch (error) { console.error('Erro na requisição:', error); return Promise.reject(error); } };
Example 2: Multiple URL parameters
TypeScriptexport const getProjectTasksController = async ( projectId: string, sprintId: string, qsParams: TaskQueryParams, ): Promise<AxiosResponse<App.Pagination<Task>, any>> => { const url = `/api/project/${projectId}/sprint/${sprintId}/tasks`; const instance = genRequestInstance(); try { const response = await instance.get(url, { params: qsParams }); return response; } catch (error) { console.error('Erro na requisição:', error); return Promise.reject(error); } };
Example 3: No URL parameters
TypeScriptexport const getAllUsersController = async ( qsParams: UserQueryParams, ): Promise<AxiosResponse<App.Pagination<User>, any>> => { const url = `/api/users`; const instance = genRequestInstance(); try { const response = await instance.get(url, { params: qsParams }); return response; } catch (error) { console.error('Erro na requisição:', error); return Promise.reject(error); } };
Recommendation▾
Add coverage of POST/PUT/DELETE methods and request body handling patterns to make it more complete
Best Practices
- Always use
{ params: qsParams }for query strings, never manual concatenation - Place required URL parameters before query string parameters in function signature
- Embed URL parameters directly in the path string using template literals
- Use consistent error handling pattern with console.error and Promise.reject
- Return the full AxiosResponse, don't extract data in controller
- Use descriptive controller function names ending with "Controller"
Common Pitfalls
- Don't mix URL parameter styles (embedding vs query string)
- Don't use
getQueryStringFromRecord()when{ params: qsParams }works - Don't modify the error object before rejecting
- Don't extract response.data in the controller - let the caller handle it
- Don't forget to await the instance.get() call