Skip to content

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

vue
<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

js
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 registry
  • resourceId (optional): ID of specific resource instance
  • extraPath (optional): Additional path segments

Returns: Request object with service configuration

js
// 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 from getResource() or similar
  • withCredentials (boolean, default: true): Include credentials in request

Request Object Properties:

  • loading (boolean): Request is in progress
  • status (number): HTTP status code
  • ok (boolean): Request was successful (200-299)
  • result (any): Response data
  • error (Error): Error object if request failed
js
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.

js
// 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.

js
// 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.

js
performAction(null, 'project', 'approve', 123, { notes: 'Approved' })

Converts a request object to a URL string.

js
const request = getResource('project', 123)
request.params = { status: 'active' }
const url = requestAsLink(request) // Returns full URL with query params

Resource Registry

The system uses a predefined registry of resources mapped to API endpoints:

js
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 - Projects
  • invoice - Invoices
  • employee - Employees
  • customer - Customers
  • milestone - Project milestones
  • assignment - Task assignments
  • department - Departments
  • timesheet - Time tracking

request-status Component

The request-status component provides visual feedback for HTTP requests with automatic error handling.

Basic Usage

vue
<template>
  <request-status 
    :request="request" 
    @ok="handleSuccess" 
    @status:400="handleBadRequest" />
</template>

Props

PropTypeDefaultDescription
requestObject-Required. Request object from useHttp()
broadcastArray[]HTTP methods that should trigger broadcasts
subscribeFunction-Callback for reactive updates
message200String-Custom success message
message201String-Custom created message
message204String-Custom deleted message
message400String-Custom bad request message
message403String-Custom forbidden message
message404String'Resource not found'Custom not found message
message500String-Custom server error message
visibleBooleantrueShow/hide the component
bgColorString'bg-transparent'Background color class

Events

EventDescriptionPayload
@okRequest succeeded (200-299)request object
@finallyRequest completed (success or error)request object
@status:200Specific status code eventsrequest object
@status:201Resource createdrequest object
@status:400Bad requestrequest object
@status:403Forbiddenrequest object
@status:404Not foundrequest object
@status:500Server errorrequest 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

vue
<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)
vue
<!-- Broadcasts updates for POST/PUT/DELETE operations -->
<request-status 
  :request="request" 
  :broadcast="['post', 'put', 'delete']" />

Manual broadcasting:

js
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

vue
<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

vue
<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

vue
<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

vue
<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:

js
onMounted(() => {
  subscribe('project', null, refreshProjects)
})

2. Handle Loading States

Always show loading feedback:

vue
<v-btn :loading="request.loading" @click="save">
  Save
</v-btn>

3. Provide User Feedback

Use the request-status component for consistent error handling:

vue
<request-status :request="request" @ok="handleSuccess" />

4. Structure Request Objects

Keep request objects in component state for reactivity:

js
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
js
// 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'