Skip to content

Add IPFS content retrieval endpoint — GET /gists/:id/content #606

@BigBen-7

Description

@BigBen-7

Description

Currently the API stores the IPFS CID on the gist record but never fetches full content back from IPFS. This issue adds GET /gists/:id/content that retrieves and returns the full JSON content from IPFS using the stored CID.

Context

  • The Gist entity has a content_cid field
  • The IpfsService has pinJson() but no getJson() method yet
  • IPFS content is fetched via an IPFS gateway, configurable via env, defaulting to https://gateway.pinata.cloud/ipfs
  • The full gist content stored on IPFS is a JSON object: { text, lat, lon, timestamp }

Requirements

  • Add getJson(cid: string) method to IpfsService
  • Fetch from IPFS gateway: GET IPFS_GATEWAY/cid
  • Add retry logic — max 3 attempts, 500ms backoff — for gateway failures
  • Add GET /gists/:id/content route to GistsController
  • The route fetches the gist by ID, gets the content_cid, then fetches from IPFS
  • Return 404 if gist not found, 502 if IPFS gateway unreachable
  • Cache the IPFS response in-memory for 5 minutes using a Map to avoid repeated gateway calls

Files to Touch

  • Backend/src/ipfs/ipfs.service.ts — add getJson method with retry logic
  • Backend/src/gists/gists.controller.ts — add @get(':id/content') route
  • Backend/src/gists/gists.service.ts — add getGistContent method
  • Backend/src/config/configuration.ts — add IPFS_GATEWAY config key
  • Backend/.env.example — add IPFS_GATEWAY=https://gateway.pinata.cloud/ipfs

getJson Implementation Reference

async getJson(cid: string): Promise<Record<string, unknown>> {
  const url = `${this.gateway}/${cid}`;
  const response = await fetch(url);
  if (!response.ok) throw new Error(`IPFS gateway error: ${response.status}`);
  return response.json();
}

Acceptance Criteria

  • GET /gists/:id/content returns the full JSON content from IPFS
  • Returns 404 if gist ID does not exist
  • Returns 502 with meaningful message if IPFS gateway fails
  • IpfsService.getJson() retries up to 3 times before failing
  • Response is cached for 5 minutes
  • Unit tests cover success, IPFS failure, and cache hit scenarios

Complexity: 250 points

Metadata

Metadata

Assignees

No one assigned

    Labels

    BackendBackend issues

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions