Kaks API-d ASP.NET Core-s: Kuidas Luua ja Ühendada

Selles juhendis selgitatakse, kuidas luua ja ühendada kaks API-d ASP.NET Core’is: üks kasutajate (Kasutaja) haldamiseks ja teine toodete (Toode) haldamiseks. Lisaks näitame, kuidas määratleda seos kasutajate ja toodete vahel nii, et üks kasutaja võib omada mitut toodet ja vastupidi.

Ülevaade

Läbi järgmiste sammude loome:

  1. Kaks API-d: Üks kasutajate (Kasutaja) ja teine toodete (Toode) haldamiseks.
  2. Seose API-de vahel: Kasutajad (Kasutaja) võivad omada mitut toodet (Toode).
  3. API kutsumine kontrollerite vahel: Teeme päringuid ühe API sees, et kasutada teise API andmeid.

Projekti Struktuur

  • KasutajadController: Kasutajate haldamiseks (Kasutaja).
  • TootedController: Toodete haldamiseks (Toode).
  • KasutajaToodeController: Kasutajate ja toodete seose haldamiseks, võimaldades kasutajatel näha, lisada ja eemaldada oma tooteid.

Samm 1: Mudelite LoomineLoo Models kausta kolm klassi: Kasutaja, Toode, ja KasutajaToode (seose jaoks).

namespace KasutajaApi.Models
{
    public class Kasutaja
    {
        public int Id { get; set; }
        public string Kasutajanimi { get; set; }
        public string Parool { get; set; }
        public string Eesnimi { get; set; }
        public string Perenimi { get; set; }

        // Suhe Toode klassiga läbi KasutajaToode
        public List<KasutajaToode> KasutajaTooted { get; set; } = new List<KasutajaToode>();
    }
}

namespace KasutajaApi.Models
{
    public class Toode
    {
        public int Id { get; set; }
        public string Name { get; set; }
        public double Price { get; set; }
        public bool IsActive { get; set; }

        // Suhe Kasutaja klassiga läbi KasutajaToode
        public List<KasutajaToode> KasutajaTooted { get; set; } = new List<KasutajaToode>();
    }
}

namespace KasutajaApi.Models
{
    public class KasutajaToode
    {
        public int KasutajaId { get; set; }
        public Kasutaja Kasutaja { get; set; }

        public int ToodeId { get; set; }
        public Toode Toode { get; set; }
    }
}

Samm 2: Seose Konfigureerimine DbContext-is

SuskeitsDbContext.cs failis loo Kasutaja ja Toode klasside vahelise seose konfigureerimine, et määrata, kuidas need klassid omavahel seotud on.

using Microsoft.EntityFrameworkCore;
using KasutajaApi.Models;

namespace KasutajaApi
{
    public class SuskeitsDbContext : DbContext
    {
        public DbSet<Kasutaja> Kasutajad { get; set; }
        public DbSet<Toode> Tooted { get; set; }
        public DbSet<KasutajaToode> KasutajaTooded { get; set; }

        public SuskeitsDbContext(DbContextOptions<SuskeitsDbContext> options) : base(options) { }

        protected override void OnModelCreating(ModelBuilder modelBuilder)
        {
            modelBuilder.Entity<KasutajaToode>()
                .HasKey(kt => new { kt.KasutajaId, kt.ToodeId });

            modelBuilder.Entity<KasutajaToode>()
                .HasOne(kt => kt.Kasutaja)
                .WithMany(k => k.KasutajaTooted)
                .HasForeignKey(kt => kt.KasutajaId);

            modelBuilder.Entity<KasutajaToode>()
                .HasOne(kt => kt.Toode)
                .WithMany(t => t.KasutajaTooted)
                .HasForeignKey(kt => kt.ToodeId);

            base.OnModelCreating(modelBuilder);
        }
    }
}

Samm 3: Kontrollerite Loomine API Otspunktide jaoks

KasutajadController.cs

See kontroller pakub otspunkte kasutajate haldamiseks.

using Microsoft.AspNetCore.Mvc;
using KasutajaApi.Models;
using System.Collections.Generic;

namespace KasutajaApi.Controllers
{
    [Route("Kasutajad")]
    [ApiController]
    public class KasutajadController : ControllerBase
    {
        private readonly SuskeitsDbContext _context;

        public KasutajadController(SuskeitsDbContext context)
        {
            _context = context;
        }

        [HttpGet]
        public ActionResult<List<Kasutaja>> Get()
        {
            return _context.Kasutajad.ToList();
        }

        [HttpPost("lisa/{id}/{kasutajanimi}/{parool}/{eesnimi}/{perenimi}")]
        public ActionResult<List<Kasutaja>> Add(int id, string kasutajanimi, string parool, string eesnimi, string perenimi)
        {
            var kasutaja = new Kasutaja { Id = id, Kasutajanimi = kasutajanimi, Parool = parool, Eesnimi = eesnimi, Perenimi = perenimi };
            _context.Kasutajad.Add(kasutaja);
            _context.SaveChanges();
            return _context.Kasutajad.ToList();
        }
    }
}

TootedController.cs

See kontroller haldab toodete andmeid.

using Microsoft.AspNetCore.Mvc;
using KasutajaApi.Models;
using System.Collections.Generic;

namespace KasutajaApi.Controllers
{
    [Route("Tooted")]
    [ApiController]
    public class TootedController : ControllerBase
    {
        private readonly SuskeitsDbContext _context;

        public TootedController(SuskeitsDbContext context)
        {
            _context = context;
        }

        [HttpGet]
        public ActionResult<List<Toode>> Get()
        {
            return _context.Tooted.ToList();
        }

        [HttpPost("lisa/{id}/{name}/{price}/{isActive}")]
        public ActionResult<List<Toode>> Add(int id, string name, double price, bool isActive)
        {
            var toode = new Toode { Id = id, Name = name, Price = price, IsActive = isActive };
            _context.Tooted.Add(toode);
            _context.SaveChanges();
            return _context.Tooted.ToList();
        }
    }
}

KasutajaToodeController.cs

See kontroller võimaldab kasutajatel oma tooteid hallata: lisada ja eemaldada tooteid ning vaadata toodete nimekirja.

using Microsoft.AspNetCore.Mvc;
using KasutajaApi.Models;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.EntityFrameworkCore;

namespace KasutajaApi.Controllers
{
    [Route("KasutajaToode")]
    [ApiController]
    public class KasutajaToodeController : ControllerBase
    {
        private readonly SuskeitsDbContext _context;

        public KasutajaToodeController(SuskeitsDbContext context)
        {
            _context = context;
        }

        [HttpGet("get-products/{userId}")]
        public async Task<IActionResult> GetProductsForUser(int userId)
        {
            var kasutaja = await _context.Kasutajad
                .Include(k => k.KasutajaTooted)
                    .ThenInclude(kt => kt.Toode)
                .FirstOrDefaultAsync(k => k.Id == userId);

            if (kasutaja == null)
            {
                return NotFound("Kasutaja ei leitud.");
            }

            var products = kasutaja.KasutajaTooted.Select(kt => kt.Toode).ToList();
            return Ok(products);
        }

        [HttpPost("add-product")]
        public async Task<IActionResult> AddProductToUser(int userId, int productId)
        {
            var kasutajaToode = new KasutajaToode { KasutajaId = userId, ToodeId = productId };
            _context.KasutajaTooded.Add(kasutajaToode);
            await _context.SaveChangesAsync();
            return Ok("Toode lisatud kasutajale.");
        }

        [HttpDelete("remove-product/{userId}/{productId}")]
        public async Task<IActionResult> RemoveProductFromUser(int userId, int productId)
        {
            var kasutajaToode = await _context.KasutajaTooded
                .FirstOrDefaultAsync(kt => kt.KasutajaId == userId && kt.ToodeId == productId);

            if (kasutajaToode == null)
            {
                return NotFound("Seos toodetega puudub.");
            }

            _context.KasutajaTooded.Remove(kasutajaToode);
            await _context.SaveChangesAsync();
            return Ok("Toode eemaldatud kasutajalt.");
        }
    }
}



Samm 4: Testi API-d

  1. Käivita projekt Visual Studios.
  2. Ava Swagger (https://localhost:/swagger), et testida kõiki API otspunkte:
    • Kõigi kasutajate vaatamine: GET /Kasutajad
    • Kõigi toodete vaatamine: GET /Tooted
    • Kasutaja toodete vaatamine: GET /KasutajaToode/get-products/{userId}
    • Toote lisamine kasutajale: POST /KasutajaToode/add-product
    • Toote eemaldamine kasutajalt: DELETE /KasutajaToode/remove-product/{userId}/{productId}

See juhend aitab teil luua ja ühendada kaks ASP.NET Core API-d, mis on seotud kasutaja ja toote haldamisega. Saate seda struktuuri vajadusel laiendada vastavalt oma projekti nõuetele

5. Kasutaja ja Toote Ühendusleht (React Rakendus)

  1. Loo uus React projekt: Loo uus React projekt, mis suhtleb ASP.NET Core API-dega aadressil https://localhost:7227.
npx create-react-app kasutaja-toode-app
cd kasutaja-toode-app

App.js: Ava projektis App.js ja muuda see vastavalt allolevale koodile. See kood loob lihtsa rakenduse, mis võimaldab hallata kasutajate ja toodete seoseid ning kuvada seotud tooted.

import { useEffect, useRef, useState } from 'react';
import './App.css';

function App() {
  const [kasutajad, setKasutajad] = useState([]);
  const [tooted, setTooted] = useState([]);
  const [selectedUser, setSelectedUser] = useState(null);
  const nameRef = useRef();
  const priceRef = useRef();
  const isActiveRef = useRef();

  // Laadi kasutajad, kui komponent laetakse
  useEffect(() => {
    fetchKasutajad();
  }, []);

  function fetchKasutajad() {
    fetch("https://localhost:7227/Kasutajad")
      .then(res => res.json())
      .then(json => setKasutajad(json))
      .catch(error => console.error('Error fetching users:', error));
  }

  function fetchTootedForUser(userId) {
    fetch(`https://localhost:7227/KasutajaToode/get-products/${userId}`)
      .then(res => res.json())
      .then(json => setTooted(json))
      .catch(error => console.error('Error fetching products:', error));
  }

  function handleUserChange(event) {
    const userId = event.target.value;
    setSelectedUser(userId);
    fetchTootedForUser(userId);
  }

  function addToodeToUser() {
    if (!selectedUser) {
      alert("Vali kasutaja, kellele toodet lisada.");
      return;
    }

    const name = nameRef.current.value;
    const price = Number(priceRef.current.value);
    const isActive = isActiveRef.current.checked;

    fetch(`https://localhost:7227/KasutajaToode/add-product?userId=${selectedUser}&name=${name}&price=${price}&isActive=${isActive}`, {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json',
      },
    })
      .then(res => res.json())
      .then(json => {
        setTooted([...tooted, json]); // Lisa uus toode loendisse
        fetchTootedForUser(selectedUser); // Värskenda tooted
      })
      .catch(error => console.error('Error adding product:', error));
  }

  function deleteToode(toodeId) {
    fetch(`https://localhost:7227/KasutajaToode/delete-product/${toodeId}`, {
      method: 'DELETE'
    })
      .then(() => {
        setTooted(tooted.filter(toode => toode.id !== toodeId));
      })
      .catch(error => console.error('Error deleting product:', error));
  }

  return (
    <div className="App">
      <h1>Kasutaja ja Toote Haldus</h1>

      <label>Vali Kasutaja</label>
      <select onChange={handleUserChange} value={selectedUser || ''}>
        <option value="" disabled>Vali kasutaja</option>
        {kasutajad.map(kasutaja => (
          <option key={kasutaja.id} value={kasutaja.id}>
            {kasutaja.kasutajanimi}
          </option>
        ))}
      </select>

      <h2>Lisa Toode</h2>
      <label>Toote Nimi</label> <br />
      <input ref={nameRef} type="text" /> <br />
      <label>Hind</label> <br />
      <input ref={priceRef} type="number" /> <br />
      <label>Aktiivne</label> <br />
      <input ref={isActiveRef} type="checkbox" /> <br />
      <button onClick={addToodeToUser}>Lisa Toode Kasutajale</button>

      <h2>Valitud Kasutaja Tooted</h2>
      {tooted.length > 0 ? (
        tooted.map(toode => (
          <div key={toode.id}>
            <div><strong>ID:</strong> {toode.id}</div>
            <div><strong>Nimi:</strong> {toode.name}</div>
            <div><strong>Hind:</strong> {toode.price}</div>
            <div><strong>Aktiivne:</strong> {toode.isActive ? 'Jah' : 'Ei'}</div>
            <button onClick={() => deleteToode(toode.id)}>Kustuta</button>
            <hr />
          </div>
        ))
      ) : (
        <p>Kasutajal pole tooteid.</p>
      )}
    </div>
  );
}

export default App;

6. API-de testimine React rakenduses

  1. Käivita rakendus: Ava terminal ja käivita React rakendus käsuga npm start.
  2. Mine aadressilehttp://localhost:3000 brauseris ja testi, et kõik töötab:
    • Vali kasutaja: Dropdown menüüst vali kasutaja.
    • Kuva tooted: Valitud kasutaja tooted kuvatakse allpool.
    • Lisa toode: Sisesta toote andmed ja vajuta nuppu “Lisa Toode Kasutajale”.
    • Kustuta toode: Iga toote kõrval on kustutamise nupp, et toode kasutajast eemaldada.
  3. API Testimine: Vaata konsoolist (F12), et jälgida kõiki päringuid ja tõrkeid, kui need ilmnevad.