使用 Spring Boot 構(gòu)建 GraphQL API

初始化 Spring Boot 項(xiàng)目

資源服務(wù)器是一個(gè)基于 Spring Boot 的 Web 應(yīng)用程序,它通過(guò) Spring for GraphQL 提供 GraphQL API。該 API 使用 Spring Data Neo4j 查詢 Neo4j 數(shù)據(jù)庫(kù)中的公司及其相關(guān)人員和屬性信息。

通過(guò) Spring Initializr 和 HTTPie 創(chuàng)建項(xiàng)目:

https start.spring.io/starter.zip 
  bootVersion==3.2.1 
  language==java 
  packaging==jar 
  javaVersion==17 
  type==gradle-project 
  dependencies==data-neo4j,graphql,docker-compose,web 
  groupId==com.okta.developer 
  artifactId==spring-graphql 
  name=="Spring Boot API" 
  description=="Demo project of a Spring Boot GraphQL API" 
  packageName==com.okta.developer.demo > spring-graphql-api.zip

解壓項(xiàng)目文件后,開始編輯項(xiàng)目。在 src/main/resources/graphql 目錄下創(chuàng)建名為 [schema](http://www.dlbhg.com/blog/ua-what-is-schema-in-database/).graphqls 的文件,定義 GraphQL API 的架構(gòu)

type Query {
  companyList(page: Int): [Company!]!
  companyCount: Int
}

type Company {
  id: ID
  SIC: String
  category: String
  companyNumber: String
  countryOfOrigin: String
  incorporationDate: String
  mortgagesOutstanding: Int
  name: String
  status: String
  controlledBy: [Person!]!
  owners: [Property!]!
}type Person {
  id: ID
  birthMonth: String
  birthYear: String
  nationality: String
  name: String
  countryOfResidence: String
}type Property {
  id: ID
  address: String
  county: String
  district: String
  titleNumber: String
}

定義領(lǐng)域模型

src/main/java 下創(chuàng)建包 com.okta.developer.demo.domain,并添加以下類:

Person 類

package com.okta.developer.demo.domain;

import org.springframework.data.neo4j.core.schema.GeneratedValue;
import org.springframework.data.neo4j.core.schema.Id;
import org.springframework.data.neo4j.core.schema.Node;@Node
public class Person {
    @Id
    @GeneratedValue
    private Long id;
    private String birthMonth;
    private String birthYear;
    private String countryOfResidence;
    private String name;
    private String nationality;    // 構(gòu)造函數(shù)、getter 和 setter 方法
}

Property 類

package com.okta.developer.demo.domain;

import org.springframework.data.neo4j.core.schema.GeneratedValue;
import org.springframework.data.neo4j.core.schema.Id;
import org.springframework.data.neo4j.core.schema.Node;@Node
public class Property {
    @Id
    @GeneratedValue
    private Long id;
    private String address;
    private String county;
    private String district;
    private String titleNumber;    // 構(gòu)造函數(shù)、getter 和 setter 方法
}

Company 類

package com.okta.developer.demo.domain;

import org.springframework.data.neo4j.core.schema.GeneratedValue;
import org.springframework.data.neo4j.core.schema.Id;
import org.springframework.data.neo4j.core.schema.Node;
import org.springframework.data.neo4j.core.schema.Relationship;import java.time.LocalDate;
import java.util.ArrayList;
import java.util.List;@Node
public class Company {
    @Id
    @GeneratedValue
    private Long id;
    private String SIC;
    private String category;
    private String companyNumber;
    private String countryOfOrigin;
    private LocalDate incorporationDate;
    private Integer mortgagesOutstanding;
    private String name;
    private String status;    @Relationship(type = "HAS_CONTROL", direction = Relationship.Direction.INCOMING)
    private List controlledBy = new ArrayList();    private List owns = new ArrayList();    // 構(gòu)造函數(shù)、getter 和 setter 方法
}

創(chuàng)建 Repository 和 Controller

CompanyRepository

package com.okta.developer.demo.repository;

import com.okta.developer.demo.domain.Company;
import org.springframework.data.neo4j.repository.ReactiveNeo4jRepository;public interface CompanyRepository extends ReactiveNeo4jRepository {
}

CompanyController

package com.okta.developer.demo.controller;

import com.okta.developer.demo.domain.Company;
import com.okta.developer.demo.repository.CompanyRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.graphql.data.method.annotation.Argument;
import org.springframework.graphql.data.method.annotation.QueryMapping;
import org.springframework.stereotype.Controller;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;@Controller
public class CompanyController {
    @Autowired
    private CompanyRepository companyRepository;    @QueryMapping
    public Flux companyList(@Argument Long page) {
        return companyRepository.findAll().skip(page * 10).take(10);
    }    @QueryMapping
    public Mono companyCount() {
        return companyRepository.count();
    }
}

構(gòu)建 React 客戶端

初始化 Next.js 項(xiàng)目

在 Spring Boot 項(xiàng)目的父目錄下運(yùn)行以下命令:

npx create-next-app@latest react-graphql

根據(jù)提示配置項(xiàng)目,并安裝必要的依賴項(xiàng):

cd react-graphql
npm install @mui/x-data-grid @mui/material @emotion/react @emotion/styled axios

創(chuàng)建 API 客戶端

src/services 目錄下創(chuàng)建 base.tsx 文件:

import axios from 'axios';

export const backendAPI = axios.create({
  baseURL: process.env.NEXT_PUBLIC_API_SERVER_URL,
});export default backendAPI;

添加 companies.tsx 文件:

import { backendAPI } from './base';

export const CompanyApi = {
  getCompanyList: async (page: number) => {
    const response = await backendAPI.post('/graphql', {
      query: { companyList(page: ${page}) { id name category } },
    });
    return response.data.data.companyList;
  },
};

創(chuàng)建數(shù)據(jù)表組件

src/components/company 目錄下創(chuàng)建 CompanyTable.tsx

import { DataGrid } from '@mui/x-data-grid';

const CompanyTable = ({ rows, columns }) => {
  return ;
};export default CompanyTable;

使用 Auth0 添加安全性

配置 Auth0

在 Auth0 中創(chuàng)建一個(gè)應(yīng)用程序,并獲取客戶端 ID 和域名。將這些信息添加到 .env.local 文件中:

NEXT_PUBLIC_AUTH0_DOMAIN=
NEXT_PUBLIC_AUTH0_CLIENT_ID=

集成 Auth0 到 React

安裝 Auth0 React SDK:

npm install @auth0/auth0-react

src/components/authentication 目錄下創(chuàng)建 Auth0ProviderWithNavigate.tsx

import { Auth0Provider } from '@auth0/auth0-react';

const Auth0ProviderWithNavigate = ({ children }) => {
  const domain = process.env.NEXT_PUBLIC_AUTH0_DOMAIN;
  const clientId = process.env.NEXT_PUBLIC_AUTH0_CLIENT_ID;  return (
    
      {children}
    
  );
};export default Auth0ProviderWithNavigate;

總結(jié)

通過(guò)本教程,您學(xué)會(huì)了如何使用 Spring Boot 構(gòu)建 GraphQL API,并通過(guò) React 客戶端消費(fèi)該 API。此外,您還了解了如何使用 Auth0 為應(yīng)用程序添加身份驗(yàn)證功能。GraphQL 的靈活性使得客戶端可以快速調(diào)整查詢以滿足需求,而 Auth0 提供了安全且便捷的身份驗(yàn)證解決方案。

原文鏈接: https://auth0.com/blog/how-to-build-a-graphql-api-with-spring-boot/
熱門推薦
一個(gè)賬號(hào)試用1000+ API
助力AI無(wú)縫鏈接物理世界 · 無(wú)需多次注冊(cè)
3000+提示詞助力AI大模型
和專業(yè)工程師共享工作效率翻倍的秘密
返回頂部
上一篇
通過(guò) Python 使用 Pexels圖片庫(kù) API 打造個(gè)性化壁紙應(yīng)用
下一篇
API密集型環(huán)境下工作流程優(yōu)化指南:避免設(shè)計(jì)失誤引發(fā)災(zāi)難
国内精品久久久久影院日本,日本中文字幕视频,99久久精品99999久久,又粗又大又黄又硬又爽毛片
欧美肥胖老妇做爰| 狠狠色丁香久久婷婷综合_中 | 欧美一区二区在线看| 欧美影片第一页| 国产亚洲成av人在线观看导航| 欧美精品一区二区蜜臀亚洲| 国产精品电影院| 成人免费观看视频| 欧美成人一区二区三区在线观看 | 中文字幕成人在线观看| 欧美一区二区观看视频| 国产精品视频看| 日本女人一区二区三区| 中文字幕乱码一区二区免费| 亚洲品质自拍视频| 国产成人在线观看| 欧美精品一区二区三区在线| 一区二区三区日韩精品视频| 国产精品77777| 日韩你懂的在线播放| 天使萌一区二区三区免费观看| 粗大黑人巨茎大战欧美成人| 日韩欧美资源站| 美腿丝袜一区二区三区| 欧美视频中文字幕| 欧美日韩精品一区二区三区四区 | 欧美一级黄色大片| 国产美女精品人人做人人爽| 国产女人aaa级久久久级| 国产成人夜色高潮福利影视| 国产精品久久久久aaaa| 972aa.com艺术欧美| 亚洲v中文字幕| 国产视频在线观看一区二区三区| 成人h动漫精品一区二区| 亚洲欧美视频在线观看视频| 欧美日韩久久久| 色欧美日韩亚洲| 狠狠色丁香婷婷综合| 久久久亚洲欧洲日产国码αv| 不卡在线视频中文字幕| 精品一区二区三区在线观看 | 成人综合激情网| 国产成人精品免费在线| 视频一区二区三区入口| 亚洲男女毛片无遮挡| 在线观看欧美日本| 色婷婷综合久色| 色八戒一区二区三区| 色综合色狠狠天天综合色| 91在线视频18| 色94色欧美sute亚洲线路二| 99re66热这里只有精品3直播| 国产成人精品影院| 国产一区在线精品| 99久久伊人久久99| 欧美色综合久久| 国产午夜精品理论片a级大结局| 日韩一卡二卡三卡| bt7086福利一区国产| 亚洲免费观看高清完整版在线观看| 久久亚洲精华国产精华液| 国产精品国产三级国产| 五月开心婷婷久久| 久草在线在线精品观看| 成人av综合在线| 欧美日韩精品一区二区| 日韩欧美国产成人一区二区| 欧美精品一区二区三区一线天视频| 国产色一区二区| 蜜臀久久久99精品久久久久久| 日韩高清欧美激情| 色菇凉天天综合网| 欧美激情自拍偷拍| 日韩色在线观看| 欧美日韩久久久一区| 色综合激情久久| 国产精品乱码一区二区三区软件| 欧美日韩国产123区| 亚洲色图.com| 色综合视频在线观看| 国产精品丝袜一区| 国产一区二区三区四区五区入口 | 一区二区三区高清| 欧美日韩国产美女| 国内久久婷婷综合| 国产aⅴ精品一区二区三区色成熟| 日本免费在线视频不卡一不卡二| 日韩一二三四区| 欧美性猛交xxxxxxxx| 91啪亚洲精品| 欧美一区二区三区色| 欧美国产日韩在线观看| 亚洲午夜私人影院| 国产经典欧美精品| 一本大道久久a久久精品综合| 精品奇米国产一区二区三区| 久久久久久电影| 亚洲欧洲精品天堂一级| 日本伊人色综合网| 尤物在线观看一区| 亚洲福利视频一区二区| 精品福利av导航| 欧美国产成人精品| 午夜视频在线观看一区二区三区 | 国产一区二区看久久| 欧美日韩一区二区在线观看视频| 欧美一区二区在线免费观看| 亚洲精品国产无天堂网2021| 男女性色大片免费观看一区二区| 国产网站一区二区| 91久久精品网| 精品日韩99亚洲| 国产亚洲精品久| 免费看精品久久片| 久久国产福利国产秒拍| 亚洲特黄一级片| 欧美日本韩国一区二区三区视频 | 成人性生交大片免费看中文 | 成人h精品动漫一区二区三区| 色诱亚洲精品久久久久久| 欧美精品一区二区在线观看| 亚洲天堂免费在线观看视频| 国产麻豆成人精品| 欧美激情在线一区二区三区| 天天操天天干天天综合网| 亚洲精品免费在线播放| 水野朝阳av一区二区三区| 欧美大片国产精品| 韩国午夜理伦三级不卡影院| 日韩欧美一级二级三级久久久| 亚洲欧美在线另类| 欧美理论片在线| 午夜精品福利在线| 久久欧美一区二区| 有码一区二区三区| 国产欧美视频在线观看| av一区二区三区四区| 日韩精品欧美精品| 久久久www成人免费毛片麻豆| 色婷婷综合激情| 久久电影网站中文字幕| 国产精品看片你懂得| 欧美一级黄色录像| 精品国产制服丝袜高跟| 国产精品资源站在线| 最新高清无码专区| 欧美tickling网站挠脚心| 亚洲综合免费观看高清在线观看| 国产精品一二三区在线| 亚洲图片欧美视频| 亚洲精品老司机| 亚洲激情五月婷婷| 亚洲男人的天堂在线观看| 亚洲va中文字幕| 亚洲主播在线播放| 日本午夜一本久久久综合| 亚洲成av人片在线观看无码| 亚洲图片激情小说| 亚洲欧洲精品一区二区精品久久久| 欧美高清视频一二三区| 欧美日韩一区精品| 欧洲人成人精品| 91污在线观看| 欧美高清www午色夜在线视频| 91欧美一区二区| 色吊一区二区三区| 欧美四级电影在线观看| 精品福利一区二区三区| 精品国产一区二区三区忘忧草 | 亚洲综合视频网| 精品奇米国产一区二区三区| 欧美三级一区二区| 日韩精品中文字幕在线一区| 欧美日韩一区二区三区不卡 | 欧美视频自拍偷拍| 国产精品久久看| 狠狠色丁香久久婷婷综合丁香| 亚洲国产岛国毛片在线| 色综合久久中文综合久久97| 国产调教视频一区| 国产清纯在线一区二区www| 亚洲精品国产视频| 欧美三级电影网站| 精品日韩成人av| 国产亚洲1区2区3区| 亚洲综合成人在线| 免费成人在线网站| 国产高清在线精品| 91精品国产综合久久久久久久| 日韩丝袜美女视频| 亚洲国产精品一区二区www| 久久成人av少妇免费| 色香色香欲天天天影视综合网| 欧美一区二区精品在线| 亚洲欧美另类综合偷拍| 一本大道久久a久久精品综合| 日本高清不卡视频| 国产精品乱码人人做人人爱 | 亚洲综合色噜噜狠狠|