HTTP Requests
Making HTTP requests in Rise follows a structured pattern that provides:
- Consistent API endpoints through resource definitions
- Reactive request state management
- Built-in error handling and status feedback
- Integration with real-time updates
Quick Start
<template>
<v-card>
<request-status :request="request" @ok="handleSuccess" />
<v-btn @click="fetchData">Fetch Data</v-btn>
<pre>{{ request.result }}</pre>
</v-card>
</template>
<script setup>
import { useHttp } from '@rise/composables/useHttp'
import { ref, onMounted } from 'vue'
const { getResource, sendRequest } = useHttp()
const request = ref({})
onMounted(() => {
request.value = getResource('projects', null) // GET /projects/
})
function fetchData() {
sendRequest(request.value)
}
function handleSuccess(response) {
console.log('Success:', response.result)
}
</script>useHttp Composable
The useHttp composable provides methods for constructing and sending HTTP requests.
Import
import { useHttp } from '@rise/composables/useHttp'
const { getResource, sendRequest, getAction, getDashboard, performAction, requestAsLink } = useHttp()Methods
getResource(name, resourceId, extraPath)
Creates a request object for a resource endpoint.
Parameters:
name(string): Resource name from the registryresourceId(optional): ID of specific resource instanceextraPath(optional): Additional path segments
Returns: Request object with service configuration
// GET /projects/
const request = getResource('project')
// GET /projects/123/
const request = getResource('project', 123)
// GET /projects/123/milestones/
const request = getResource('project', 123, 'milestones/')sendRequest(request, withCredentials)
Executes an HTTP request and updates the request object with response data.
Parameters:
request(object): Request object fromgetResource()or similarwithCredentials(boolean, default: true): Include credentials in request
Request Object Properties:
loading(boolean): Request is in progressstatus(number): HTTP status codeok(boolean): Request was successful (200-299)result(any): Response dataerror(Error): Error object if request failed
const request = getResource('project', 123)
await sendRequest(request)
if (request.ok) {
console.log('Data:', request.result)
} else {
console.log('Error:', request.status)
}getAction(resource, actionId, resourceId)
Creates a request object for performing actions on resources.
// POST /projects/123/actions/approve/
const request = getAction('project', 'approve', 123)
request.data = { notes: 'Approved by manager' }
sendRequest(request)getDashboard(resource, dashboardId, resourceId)
Creates a request object for dashboard endpoints.
// GET /projects/123/dashboards/analytics/
const request = getDashboard('project', 'analytics', 123)
sendRequest(request)performAction(request, resource, actionId, resourceId, data)
Convenience method to perform an action in one call.
performAction(null, 'project', 'approve', 123, { notes: 'Approved' })requestAsLink(request, extraParams)
Converts a request object to a URL string.
const request = getResource('project', 123)
request.params = { status: 'active' }
const url = requestAsLink(request) // Returns full URL with query paramsResource Registry
The system uses a predefined registry of resources mapped to API endpoints:
const REGISTRY = {
"project": { service: 'api', path: "/projects/" },
"invoice": { service: 'api', path: "/invoices/" },
"employee": { service: 'api', path: "/employees/" },
"customer": { service: 'api', path: "/customers/" },
// ... more resources
}Available Resources
Common resources include:
project- Projectsinvoice- Invoicesemployee- Employeescustomer- Customersmilestone- Project milestonesassignment- Task assignmentsdepartment- Departmentstimesheet- Time tracking
request-status Component
The request-status component provides visual feedback for HTTP requests with automatic error handling.
Basic Usage
<template>
<request-status
:request="request"
@ok="handleSuccess"
@status:400="handleBadRequest" />
</template>Props
| Prop | Type | Default | Description |
|---|---|---|---|
request | Object | - | Required. Request object from useHttp() |
broadcast | Array | [] | HTTP methods that should trigger broadcasts |
subscribe | Function | - | Callback for reactive updates |
message200 | String | - | Custom success message |
message201 | String | - | Custom created message |
message204 | String | - | Custom deleted message |
message400 | String | - | Custom bad request message |
message403 | String | - | Custom forbidden message |
message404 | String | 'Resource not found' | Custom not found message |
message500 | String | - | Custom server error message |
visible | Boolean | true | Show/hide the component |
bgColor | String | 'bg-transparent' | Background color class |
Events
| Event | Description | Payload |
|---|---|---|
@ok | Request succeeded (200-299) | request object |
@finally | Request completed (success or error) | request object |
@status:200 | Specific status code events | request object |
@status:201 | Resource created | request object |
@status:400 | Bad request | request object |
@status:403 | Forbidden | request object |
@status:404 | Not found | request object |
@status:500 | Server error | request object |
Features
- Loading State: Shows progress indicator during requests
- Error Handling: Displays appropriate error messages and retry options
- Success Feedback: Configurable success messages via snackbars
- Reactive Integration: Automatically broadcasts updates when enabled
Reactive Updates
The system includes real-time reactivity through the useReactiveStore composable.
Subscribe to Changes
<script setup>
import { useReactiveStore } from '@rise/composables/useReactiveStore'
import { onMounted } from 'vue'
const { subscribe } = useReactiveStore()
onMounted(() => {
// Subscribe to any changes to 'project' resources
subscribe('project', null, handleProjectUpdate)
// Subscribe to changes to a specific project
subscribe('project', 123, handleSpecificProjectUpdate)
})
function handleProjectUpdate(resource, resourceId) {
console.log(`Project ${resourceId} was updated`)
// Refresh your data here
}
</script>Broadcasting Changes
The request-status component automatically broadcasts updates when:
- The request succeeds (status 200-299)
- The request method is not GET
- Broadcasting is enabled (default)
<!-- Broadcasts updates for POST/PUT/DELETE operations -->
<request-status
:request="request"
:broadcast="['post', 'put', 'delete']" />Manual broadcasting:
import { useReactiveStore } from '@rise/composables/useReactiveStore'
const { broadcast } = useReactiveStore()
// Notify all subscribers that project 123 was updated
broadcast('project', 123)Advanced Examples
Form with Validation
<template>
<v-form @submit.prevent="save">
<request-status
:request="request"
@ok="handleSaved"
@status:400="handleValidationErrors" />
<v-text-field
v-model="formData.name"
label="Project Name"
:error-messages="getFieldErrors('name')" />
<v-btn type="submit" :loading="request.loading">
Save Project
</v-btn>
</v-form>
</template>
<script setup>
import { useHttp } from '@rise/composables/useHttp'
import { ref } from 'vue'
const { getResource, sendRequest } = useHttp()
const formData = ref({ name: '' })
const request = ref({})
const validationErrors = ref({})
function save() {
const req = getResource('project')
req.method = 'post'
req.data = formData.value
request.value = req
sendRequest(req)
}
function handleSaved(response) {
console.log('Project saved:', response.result)
// Redirect or close form
}
function handleValidationErrors(response) {
validationErrors.value = response.result || {}
}
function getFieldErrors(fieldName) {
return validationErrors.value[fieldName] || []
}
</script>List with Real-time Updates
<template>
<v-card>
<request-status :request="request" @ok="loadProjects" />
<v-list>
<v-list-item
v-for="project in projects"
:key="project.id"
:title="project.name" />
</v-list>
<v-btn @click="refresh">Refresh</v-btn>
</v-card>
</template>
<script setup>
import { useHttp } from '@rise/composables/useHttp'
import { useReactiveStore } from '@rise/composables/useReactiveStore'
import { ref, onMounted } from 'vue'
const { getResource, sendRequest } = useHttp()
const { subscribe } = useReactiveStore()
const request = ref({})
const projects = ref([])
onMounted(() => {
request.value = getResource('project')
refresh()
// Auto-refresh when any project changes
subscribe('project', null, refresh)
})
function refresh() {
sendRequest(request.value)
}
function loadProjects(response) {
projects.value = response.result.results || []
}
</script>File Uploads
<template>
<v-form @submit.prevent="upload">
<request-status :request="request" @ok="handleUploaded" />
<v-file-input
v-model="files"
label="Select files"
multiple />
<v-btn type="submit" :loading="request.loading">
Upload
</v-btn>
</v-form>
</template>
<script setup>
import { useHttp } from '@rise/composables/useHttp'
import { ref } from 'vue'
const { getResource, sendRequest } = useHttp()
const files = ref([])
const request = ref({})
function upload() {
const formData = new FormData()
files.value.forEach(file => {
formData.append('files', file)
})
const req = getResource('project', 123, 'upload/')
req.method = 'post'
req.formData = formData
request.value = req
sendRequest(req)
}
function handleUploaded(response) {
console.log('Files uploaded:', response.result)
}
</script>Error Handling
The system provides multiple levels of error handling:
Automatic Error Display
The request-status component automatically shows:
- 400 Bad Request: Form validation errors
- 403 Forbidden: Permission denied with retry option
- 404 Not Found: Resource not found message
- 500+ Server Errors: Generic server error with retry option
Custom Error Handling
<template>
<request-status
:request="request"
@status:403="handlePermissionDenied"
@status:404="handleNotFound"
@status:500="handleServerError" />
</template>
<script setup>
function handlePermissionDenied(request) {
// Custom permission denied logic
console.log('Access denied to:', request.path)
}
function handleNotFound(request) {
// Custom not found logic
router.push('/404')
}
function handleServerError(request) {
// Custom server error logic
console.error('Server error:', request.result)
}
</script>Best Practices
1. Use Reactive Subscriptions
Subscribe to resource changes to keep your UI in sync:
onMounted(() => {
subscribe('project', null, refreshProjects)
})2. Handle Loading States
Always show loading feedback:
<v-btn :loading="request.loading" @click="save">
Save
</v-btn>3. Provide User Feedback
Use the request-status component for consistent error handling:
<request-status :request="request" @ok="handleSuccess" />4. Structure Request Objects
Keep request objects in component state for reactivity:
const requests = ref({
get: {},
save: {},
delete: {}
})5. Use Proper HTTP Methods
Follow REST conventions:
- GET for fetching data
- POST for creating resources
- PUT/PATCH for updates
- DELETE for removal
// Create
const req = getResource('project')
req.method = 'post'
req.data = projectData
// Update
const req = getResource('project', 123)
req.method = 'patch'
req.data = updates
// Delete
const req = getResource('project', 123)
req.method = 'delete'