Skip to content

fassahat/crypto_ql

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

1 Commit
 
 
 
 
 
 
 
 
 
 

Repository files navigation

CryptoQL

A GraphQL API that wraps the CoinGecko public REST API, built with Apollo Server v4 and Node.js. No database required — all data comes from CoinGecko in real time.

Features

  • 4 Queries — coin details, top coins by market cap, search, global market overview
  • 1 Mutation — live currency conversion using CoinGecko prices
  • Custom error handling — structured GraphQL errors (NOT_FOUND, VALIDATION_ERROR, RATE_LIMITED, UPSTREAM_ERROR)
  • Dedicated data source — all CoinGecko HTTP calls are isolated in CoinGeckoAPI
  • Zero config — no API key needed (uses CoinGecko's free tier)

Quick Start

# Install dependencies
npm install

# Start the server (port 4000 by default)
npm start

# Or start with auto-reload during development
npm run dev

Open http://localhost:4000 in your browser to access the Apollo Sandbox.

Environment Variables

Variable Default Description
PORT 4000 HTTP port to listen on

Testing the API

Apollo Sandbox (browser)

Start the server with npm start and open http://localhost:4000. Apollo Sandbox provides an interactive editor with autocomplete, schema docs, and a history of past queries.

cURL

# Fetch Bitcoin details
curl -s http://localhost:4000/ \
  -H 'Content-Type: application/json' \
  -d '{"query":"{ coin(id: \"bitcoin\") { name currentPrice marketCapRank } }"}' | jq

# Top 5 coins
curl -s http://localhost:4000/ \
  -H 'Content-Type: application/json' \
  -d '{"query":"{ topCoins(limit: 5) { name currentPrice priceChangePercentage24h } }"}' | jq

# Search
curl -s http://localhost:4000/ \
  -H 'Content-Type: application/json' \
  -d '{"query":"{ searchCoins(query: \"sol\") { coins { id name symbol } } }"}' | jq

# Global market
curl -s http://localhost:4000/ \
  -H 'Content-Type: application/json' \
  -d '{"query":"{ globalMarket { totalMarketCap marketCapPercentage { btc eth } } }"}' | jq

# Convert 1 ETH to USD
curl -s http://localhost:4000/ \
  -H 'Content-Type: application/json' \
  -d '{"query":"mutation { convertCurrency(fromCoinId: \"ethereum\", toCurrency: \"usd\", amount: 1) { convertedAmount rate timestamp } }"}' | jq

Tip: Pipe through jq for pretty-printed output. Remove | jq if you don't have it installed.

Schema Overview

Queries

Query Description
coin(id) Detailed data for a single cryptocurrency
topCoins Top coins ranked by market cap
searchCoins Search coins by name or symbol
globalMarket Global crypto market overview

Mutations

Mutation Description
convertCurrency Convert an amount from one crypto to another currency

Example Queries

Fetch a single coin

query GetBitcoin {
  coin(id: "bitcoin") {
    id
    name
    symbol
    currentPrice
    marketCap
    marketCapRank
    priceChangePercentage24h
    high24h
    low24h
    circulatingSupply
    ath
    athDate
    description
    homepage
  }
}

List top coins by market cap

query TopCoins {
  topCoins(currency: "usd", limit: 5, page: 1) {
    id
    name
    symbol
    currentPrice
    marketCap
    marketCapRank
    priceChangePercentage24h
    totalVolume
  }
}

Search for coins

query Search {
  searchCoins(query: "ethereum") {
    coins {
      id
      name
      symbol
      marketCapRank
      thumb
    }
  }
}

Global market overview

query GlobalOverview {
  globalMarket {
    activeCryptocurrencies
    markets
    totalMarketCap
    totalVolume
    marketCapPercentage {
      btc
      eth
    }
    marketCapChangePercentage24h
    updatedAt
  }
}

Convert currency (mutation)

mutation Convert {
  convertCurrency(fromCoinId: "bitcoin", toCurrency: "usd", amount: 2.5) {
    from
    to
    amount
    convertedAmount
    rate
    timestamp
  }
}

Error handling examples

Invalid coin ID:

query {
  coin(id: "not_a_real_coin") {
    name
  }
}

Response:

{
  "errors": [
    {
      "message": "CoinGecko resource not found (Not Found)",
      "extensions": { "code": "NOT_FOUND" }
    }
  ],
  "data": { "coin": null }
}

Validation error (negative amount):

mutation {
  convertCurrency(fromCoinId: "bitcoin", toCurrency: "usd", amount: -5) {
    convertedAmount
  }
}

Response:

{
  "errors": [
    {
      "message": "amount must be a positive number",
      "extensions": { "code": "VALIDATION_ERROR" }
    }
  ],
  "data": null
}

Project Structure

crypto_ql/
├── src/
│   ├── index.js                  # Apollo Server entry point
│   ├── schema.js                 # GraphQL type definitions
│   ├── resolvers.js              # Query & mutation resolvers
│   ├── datasources/
│   │   └── CoinGeckoAPI.js       # All CoinGecko REST calls
│   └── errors/
│       └── index.js              # Custom GraphQL error classes
├── .gitignore
├── package.json
└── readme.md

Error Codes

Code HTTP Status Description
NOT_FOUND 404 Requested coin/resource not found
VALIDATION_ERROR 400 Invalid input (empty ID, negative amount, etc.)
RATE_LIMITED 429 CoinGecko rate limit exceeded
UPSTREAM_ERROR 502 Unexpected CoinGecko API failure

Tech Stack

  • Runtime: Node.js
  • GraphQL Server: Apollo Server v4
  • Data Source: CoinGecko public API (no key required)
  • HTTP Client: node-fetch v2

License

MIT

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors