Desarrollo y Mantenimiento de Sistemas Informáticos

4º. 1er cuatrimestre. Itinerario de Sistemas de la Información. Grado en Ingeniería Informática. ULL


GH Org   - GH Template Org   - GitHub Classroom   - Discussions   - Teams   - Campus ULL   - Students Activity   - Chat   - Google Meet

Práctica Introducción a Next.js

You must reproduce the example taught during the class 2024-11-27 using v0.dev and Claude AI. Although the v0 answer is in TypeScript you can instead use JS for your solution. Some of the contents here are the AIs literal responses. If you find any errors let us know.

v0 Answer to questions about making a request to GitHub from a Next.js program

Question: I have a server side next.js function and I want to access the variables in the path of a request to GitHub REST api like in https://api.github.com/users/${username}/repos?1.

Here is the answer from v0.dev


I can help you with accessing variables in the path of a GitHub REST API request within a server-side Next.js function. This is a common pattern when working with dynamic API endpoints. Let’s break this down step by step:

Here’s an example of how you can create a server-side function in Next.js that accesses the username variable in the path of a GitHub REST API request:

Folder Hierarchy

Code for file pages/user/[username].tsx

import { GetServerSideProps } from 'next'
import Link from 'next/link'

interface Repo {
  id: number
  name: string
  html_url: string
}

interface Props {
  repos: Repo[]
  username: string
}

export const getServerSideProps: GetServerSideProps<Props> = async (context) => {
  const username = context.params?.username as string

  try {
    const res = await fetch(`${process.env.NEXT_PUBLIC_API_URL}/api/github-repos/${username}`)
    
    if (!res.ok) {
      throw new Error('Failed to fetch repos')
    }

    const repos: Repo[] = await res.json()

    return {
      props: {
        repos,
        username,
      },
    }
  } catch (error) {
    console.error('Error in getServerSideProps:', error)
    return {
      props: {
        repos: [],
        username,
      },
    }
  }
}

export default function UserRepos({ repos, username }: Props) {
  return (
    <div className="mt-4">
      <h2 className="text-xl font-semibold mb-2">{username}'s Repositories</h2>
      {repos.length > 0 ? (
        <ul className="list-disc pl-5">
          {repos.map((repo) => (
            <li key={repo.id} className="mb-1">
              <a href={repo.html_url} target="_blank" rel="noopener noreferrer" className="text-blue-500 hover:underline">
                {repo.name}
              </a>
            </li>
          ))}
        </ul>
      ) : (
        <p>No repositories found.</p>
      )}
      <Link href="/" className="mt-4 inline-block text-blue-500 hover:underline">
        Back to Home
      </Link>
    </div>
  )
}

Code for pages/api/github-repos/[username].ts

import type { NextApiRequest, NextApiResponse } from 'next'

export default async function handler(
  req: NextApiRequest,
  res: NextApiResponse
) {
  const { username } = req.query

  if (!username || typeof username !== 'string') {
    return res.status(400).json({ error: 'Username is required' })
  }

  try {
    const response = await fetch(`https://api.github.com/users/${username}/repos`)
    
    if (!response.ok) {
      throw new Error('Failed to fetch repos')
    }

    const repos = await response.json()
    res.status(200).json(repos)
  } catch (error) {
    console.error('Error fetching repos:', error)
    res.status(500).json({ error: 'Failed to fetch repos' })
  }
}

Code for pages/index.tsx

import { useState } from 'react'
import { useRouter } from 'next/router'
import UserRepos from './user/[username]'

export default function Home() {
  const [username, setUsername] = useState('')
  const router = useRouter()

  const handleSubmit = (e: React.FormEvent) => {
    e.preventDefault()
    if (username) {
      router.push(`/user/${username}`)
    }
  }

  return (
    <div className="container mx-auto p-4">
      <h1 className="text-2xl font-bold mb-4">GitHub Repository Viewer</h1>
      <form onSubmit={handleSubmit} className="mb-4">
        <input
          type="text"
          value={username}
          onChange={(e) => setUsername(e.target.value)}
          placeholder="Enter GitHub username"
          className="border p-2 mr-2"
        />
        <button type="submit" className="bg-blue-500 text-white p-2 rounded">
          View Repos
        </button>
      </form>
      {router.query.username && (
        <UserRepos
          repos={[]} // This will be populated by getServerSideProps in the actual component
          username={router.query.username as string}
        />
      )}
    </div>
  )
}

Explanations by v0

In this example:

  1. We create an API route at pages/api/github-repos/[username].ts. This route uses the username from the query parameters to make a request to the GitHub API.
  2. In the pages/user/[username].tsx file, we use getServerSideProps to fetch data server-side. This function receives the context object, which includes the params from the URL .
  3. We extract the username from context.params and use it to make a request to our own API route.
  4. The component then receives the fetched repos as props and renders them.

To use this, you would navigate to a URL like /user/octocat, and it would display the repositories for the GitHub user “octocat”.

Remember to set the NEXT_PUBLIC_API_URL environment variable to your application’s URL (e.g., http://localhost:3000 for local development).

This approach allows you to securely handle API keys (if needed) on the server side while still providing dynamic content based on the URL parameters.

Claude AI’s Answer to Explain getserversideprops from next.js

Rúbrica

Actividad

  1. Aaron repo , Commits, Commit Activity and Summary
  2. Alejandro repo , Commits, Commit Activity and Summary
  3. Casiano repo , Commits, Commit Activity and Summary