Hone logo
Hone
Problems

Building a Reactive Platform API in Vue.js with TypeScript

This challenge focuses on creating a simulated platform API service within a Vue.js application using TypeScript. You will implement a core service that mimics fetching and managing data from a backend, allowing your Vue components to interact with it in a reactive and organized manner. This is crucial for building scalable and maintainable frontend applications that depend on dynamic data.

Problem Description

Your task is to create a TypeScript-based "Platform API" service in your Vue.js project. This service will simulate common API interactions like fetching lists of resources, getting a single resource by its ID, and potentially creating or updating resources. The key is to make these operations reactive, meaning that when the data within the service changes, any Vue component subscribed to it should automatically update.

Key Requirements:

  1. Service Structure: Create a dedicated TypeScript service file (e.g., platformApi.ts) to encapsulate all API-related logic.
  2. Resource Simulation: Simulate at least two distinct resource types (e.g., Users, Products, Posts). For each resource, maintain an in-memory array to hold its data.
  3. Fetching Data:
    • Implement a method to fetch a list of all resources of a given type (e.g., fetchUsers(), fetchProducts()).
    • Implement a method to fetch a single resource by its unique identifier (e.g., getUserById(id: string)).
  4. Reactivity: Utilize Vue's reactivity system (e.g., ref, reactive, computed) to make the fetched data observable by Vue components. When data is updated in the service, components should reflect these changes.
  5. Data Manipulation (Optional but Recommended):
    • Implement methods to add a new resource (e.g., addUser(userData)).
    • Implement methods to update an existing resource (e.g., updateUser(id: string, updatedData)).
  6. Error Handling: Implement basic error handling for simulated API calls (e.g., if a resource ID is not found).
  7. TypeScript Integration: All service methods, data structures, and return types should be strongly typed using TypeScript.

Expected Behavior:

  • When fetchUsers() is called, it should return a promise that resolves with an array of user objects. This array should be reactive.
  • When getUserById('123') is called, it should return a promise that resolves with the user object matching the ID, or undefined if not found.
  • If a component uses the reactive user list and a new user is added via the service, the component should automatically update to display the new user.

Edge Cases:

  • Fetching a resource that does not exist.
  • Attempting to update or delete a non-existent resource.
  • Concurrency issues (though less critical for a simulated API, consider how multiple components might interact with the service).

Examples

Let's assume we are simulating User resources.

Example 1: Fetching a List of Users

  • Input: No direct input to the fetchUsers method itself (it operates on the service's internal state).
  • Output: A reactive reference containing an array of user objects, or null/undefined if not yet fetched or an error occurred.
// Internal simulated data in the API service
const users = [
  { id: '1', name: 'Alice', email: 'alice@example.com' },
  { id: '2', name: 'Bob', email: 'bob@example.com' }
];

// In a Vue component:
// const usersList = platformApi.getUsers(); // Assuming platformApi exposes this reactive ref
// This `usersList` would contain the above data reactively.

Example 2: Fetching a Single User by ID

  • Input: platformApi.getUserById('1')
  • Output: A promise resolving to a single user object:
{ id: '1', name: 'Alice', email: 'alice@example.com' }
  • Explanation: The service finds the user with id: '1' in its internal users array and returns it.

Example 3: Handling Non-Existent Resource

  • Input: platformApi.getUserById('999')
  • Output: A promise resolving to undefined (or an error, depending on implementation).
  • Explanation: The service searches for a user with id: '999', does not find one, and indicates its absence.

Constraints

  • The solution must be implemented within a Vue 3 project using the Composition API.
  • All code related to the API service must be written in TypeScript.
  • The simulated API should use in-memory arrays for data storage. No actual network requests are required.
  • The API service should expose methods that return Promises, mimicking asynchronous API calls.
  • The reactive data management within the service should be handled using Vue 3's Composition API reactivity primitives (ref, computed, reactive).

Notes

  • Consider using a factory function or a singleton pattern to manage your API service instance across your Vue application.
  • Think about how you will expose the reactive data to your components. Should the methods return reactive refs directly, or should components subscribe to them?
  • For simulating ids, simple string or number increments are sufficient.
  • You can start with just two resource types (e.g., users and posts) and expand from there.
  • Consider the naming conventions for your API methods (e.g., fetch..., get..., create..., update..., delete...).
  • How will you handle the initial fetching of data? Will it be on component mount, or can it be triggered manually?
Loading editor...
typescript