Technologies used
Backend:
- Typescript
- Node.js
- Express
- Apollo Server v4
- sqlite
- Prisma
Frontend:
- Typescript
- React
- Apollo Client
- Tailwindcss
- vite
1 - Project setup
① Create a project
mkdir <Project Name>
cd <Project Name>
npm init -y
② Use the workspace function
※ A function that manages multiple functions.
mkdir packages
③ Add code to package.json
//省略
"license": "ISC",
"workspaces": [
"packages/*"
],
④ Create frontend and backend folders in packages folder
⑤ Open three terminals and rename them root, frontend, and backend.
⑥ Go to backend terminal
cd packages/backend/
npm init -y
⑦ Go to frontend terminal
cd packages/frontend/
npm create vite@latest . -- --template react-ts
⑧ Go to root terminal
npm i
⑨ Allow root to control forontend and backend
//省略
"scripts": {
"dev:front": "npm run dev -w frontend"
},
npm run dev:front
⑩ Prepare typescript in backend
Create src folder and index.ts
npm i -DE typescript @types/node nodemon
touch backend
{
"compilerOptions": {
"target": "ES2022",
"module": "NodeNext",
"outDir": "./dist",
"esModuleInterop": true,
"forceConsistentCasingInFileNames": true,
"allowSyntheticDefaultImports": true,
"strict": true,
"skipLibCheck": true,
"moduleResolution": "NodeNext"
}
}
//省略
"main": "index.js",
"type": "module",
"scripts": {
"dev": "nodemon dist/index.js",
"watch":"tsc --watch",
"build":"tsc",
"start": "node dist/index.js",
"lint":"eslint --fix \"./src/**/*.{js,jsx,ts,tsx,json}\""
npm run lint
⑪ Allow root to control forontend and backend
//省略
"scripts": {
"build": "npm run build:back && npm run build:front",
"build:back": "npm run build -w backend",
"build:front": "npm run build -w frontend",
"dev:back": "npm run dev -w backend",
"watch:back": "npm run watch -w backend",
"dev:front": "npm run dev -w frontend"
},
npm run build
⑫ Add eslint to backend
npm i -ED eslint
npx eslint --init
※ shift + option + f (Run Prettier)
//省略
extends: [
'eslint:recommended',
'plugin:@typescript-eslint/recommended',
'plugin:@typescript-eslint/recommended-requiring-type-checking',
],
//省略
parserOptions: {
sourceType: 'script',
tsconfigRootDir: __dirname,//Add code
project: ['tsconfig.eslint.json'],//Add code
},
⑬ Add tsconfig.eslint.json to backend/src
{
"extends": "./tsconfig.json",
"include": ["src/**/*.ts", ".eslintrc.cjs"],
"exclude": ["node_modules"]
}
※ shift + command + p (open command palette:Developer:Reload Window)
⑭ Add eslint to frontend
npm i -ED eslint
npx eslint --init
npm i -ED eslint-plugin-react-hooks
extends: [
'eslint:recommended',
'plugin:react/recommended',
'plugin:react-hooks/recommended',//Add code
'plugin:@typescript-eslint/recommended',
],
//省略
parserOptions: {
sourceType: 'script',
tsconfigRootDir: __dirname,//Add code
project: ['tsconfig.eslint.json'],//Add code
},
⑮ Add tsconfig.eslint.json to frontend/src
{
"extends": "./tsconfig.json",
"include": ["src/**/*.ts", ".eslintrc.cjs"],
"exclude": ["node_modules"]
}
2 - Launching a minimal Apollo server
① Enter the backend terminal and install the necessary libraries
npm i express graphql @apollo/server
npm i -ED @types/express
② Start up apollo server
import http from 'http';
import { ApolloServer } from '@apollo/server';
import { ApolloServerPluginDrainHttpServer } from '@apollo/server/plugin/drainHttpServer';
import { expressMiddleware } from '@apollo/server/express4';
import express from 'express';
import { mergeResolvers, mergeTypeDefs } from '@graphql-tools/merge';
const typeDefs = `#graphql
type Query {
health: Boolean
}
`;
const resolvers = {
Query: {
health: async (_: any, args: any, context: MyContext, info: any) => {
return true;
},
},
};
type MyContext = {
req: express.Request;
res: express.Response;
};
async function main() {
const PORT = process.env.PORT || 5555;
const app = express();
const httpSever = http.createServer(app);
const server = new ApolloServer<MyContext>({
typeDefs: mergeTypeDefs([typeDefs]),
resolvers: mergeResolvers([resolvers]),
plugins: [ApolloServerPluginDrainHttpServer({ httpServer: httpSever })],
});
await server.start();
app.use(express.json());
app.use(
'/graphql',
expressMiddleware(server, {
context: async ({ req, res }) => ({ req, res }),
})
);
await new Promise<void>((resolve) => {
httpSever.listen({ port: PORT }, resolve);
});
console.log(`server is up and running at http://localhost:{PORT}`);
}
main().catch((error) => {
console.error(error);
process.exit(1);
});
3 - Adding a Graphql code generator
① Create modules/root/greet/greet.typeDefs.ts for refactoring
const typeDefs = `#graphql
type Query {
greet: String
}
`;
export default typeDefs;
② Create modules/root/greet/greet.resolversts.ts for refactoring
import { MyContext } from '../../../types/graphql.js';
const resolvers = {
Query: {
health: async (_: any, args: any, context: MyContext, info: any) => {
return true;
},
},
};
export default resolvers;
③ Create/types/graphql.ts
import express from 'express';
export type MyContext = {
req: express.Request;
res: express.Response;
};
④ Refactor backend/src/index.ts
import http from 'http';
import { ApolloServer } from '@apollo/server';
import { ApolloServerPluginDrainHttpServer } from '@apollo/server/plugin/drainHttpServer';
import { expressMiddleware } from '@apollo/server/express4';
import express from 'express';
import { mergeResolvers, mergeTypeDefs } from '@graphql-tools/merge';
import { MyContext } from './types/graphql.js';
import greetTypeDefs from './modules/root/greet/greet.typeDefs.js';
import greetResolvers from './modules/root/greet/greet.resolversts.js';
import makeTodoTypeDefs from './modules/todos/make-todo/make-todo.typeDefs.js';
import makeTodoResolvers from './modules/todos/make-todo/make-todo.resolvers.js';
import TodoTypeDefs from './modules/root/models/todo.typeDefs.js';
async function main() {
const PORT = process.env.PORT || 5555;
const app = express();
const httpSever = http.createServer(app);
const server = new ApolloServer<MyContext>({
typeDefs: mergeTypeDefs([greetTypeDefs, makeTodoTypeDefs, TodoTypeDefs]),
resolvers: mergeResolvers([greetResolvers, makeTodoResolvers]),
plugins: [ApolloServerPluginDrainHttpServer({ httpServer: httpSever })],
});
await server.start();
app.use(express.json());
app.use(
'/graphql',
expressMiddleware(server, {
context: async ({ req, res }) => ({ req, res }),
})
);
await new Promise<void>((resolve) => {
httpSever.listen({ port: PORT }, resolve);
});
console.log(`server is up and running at http://localhost:{PORT}`);
}
main().catch((error) => {
console.error(error);
process.exit(1);
});
⑤ Create todos folder get-todo, get-todos, make-todo,
remove-todo, update-todo folder in modules folder
⑥ Create make-todo.typeDefs.ts and make-todo.resolvers.ts in make-todo
const typeDefs = `#graphql
input MakeTodoInput {
title: String!
}
type MakeTodoRespose {
todo:Todo!
}
type Mutation {
makeTodo(MakeTodoInput:MakeTodoInput!):MakeTodoRespose!
}
`;
export default typeDefs;
import { title } from 'process';
import { Resolvers } from '../../../_generated_/graphql.js';
import { MyContext } from '../../../types/graphql.js';
import crypto from 'crypto';
const resolvers: Resolvers<MyContext> = {
Mutation: {
makeTodo: async (
_: any,
args: { makeTodoInput },
context: MyContext,
info: any
) => {
const todoItem = {
id: crypto.randomUUID(),
title: makeTodoInput.title,
updatedAt: new Date().toISOString(),
createdAt: new Date().toISOString(),
};
return 'todo has been created !';
},
},
};
export default resolvers;
⑦ Automate type specification
npm i -ED @graphql-codegen/cli
npx graphql-code-generator init
import { Resolvers } from '../../../_generated_/graphql.js';
import { MyContext } from '../../../types/graphql.js';
import crypto from 'crypto';
const resolvers: Resolvers<MyContext> = {
Mutation: {
makeTodo: async (
_: any,
args: { makeTodoInput },
context: MyContext,
info: any
) => {
const todoItem = {
id: crypto.randomUUID(),
title: makeTodoInput.title,
updatedAt: new Date().toISOString(),
createdAt: new Date().toISOString(),
};
return 'todo has been created !';
},
},
};
export default resolvers;
⑧ Create a files generated by codegen.yml
overwrite: true
schema: 'http://localhost:5555/graphql'
generates:
src/_generated_/graphql.ts:
plugins:
- 'typescript'
- 'typescript-resolvers'
⑨ Remove ^ in package.json and run npm i
npm i
⑩ backend/src/generated/graphql.ts
⑪ type Todo {
id: String!
title: String!
updatedAt: String!
createdAt: String!
} will be used elsewhere, so create a file to share.
create root/models/todo.typeDefs.ts
const typeDefs = `#graphql
type Todo {
id: String!
title: String!
updatedAt: String!
createdAt: String!
}
`;
export default typeDefs;
4 - Automatic import of TypeDefs and Resolvers
① Install the library
//backend
npm i -E glob
npm i -ED @types/glob copyfiles
② Create buildSchema.ts in the utils folder
③ Create make-todo.graphql in make-todo folder
④ Create greet.graphql in greet folder
⑤ Delete make-todo.typeDefs.ts in make-todo folder
⑥ Delete greet.typeDefs.ts in greet folder
⑦ Create todo.graphql in modeles folder
⑧ Delete todo.typeDefs.ts in greet folder
⑨ Refactor backend/src/index.ts
⑩ Add code to backend/src/package.json
//省略
"scripts": {
//省略
"gen": "graphql-codegen --config codegen.yml",
"cpgql": "copyfiles -u 1 src/**/*.graphql ./dist "
},
5 - Prisma preparation & TodoCRUD implementation
公式サイト:prisma
① Install prisma in your backend project
npm i -E prisma@prisma/client
npx prisma init
② Edit .env in backend
DATABASE_URL="file:./dev.db"
③ Add code to prisma/schema.prisma
generator client {
provider = "prisma-client-js"
}
datasource db {
provider = "sqlite"
url = env("DATABASE_URL")
}
model Todo{
id String @id @default(uuid())
title String
isCompleted Boolean @default(false)
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
}
④ Create migration file in backend
npx prisma migrate dev --name init
npx prisma studio //server starts up
④ Edit backend/src/index.ts to use Prisma
import http from 'http';
import { ApolloServer } from '@apollo/server';
import { ApolloServerPluginDrainHttpServer } from '@apollo/server/plugin/drainHttpServer';
import { expressMiddleware } from '@apollo/server/express4';
import express from 'express';
import { PrismaClient } from '@prisma/client';
import { MyContext } from './types/graphql.js';
import { buildSchema } from './utils/buildSchema.js';
const prismaClient = new PrismaClient();
async function main() {
await prismaClient.$connect();
const PORT = process.env.PORT || 5555;
const app = express();
const httpSever = http.createServer(app);
const server = new ApolloServer<MyContext>({
schema: await buildSchema(),
plugins: [ApolloServerPluginDrainHttpServer({ httpServer: httpSever })],
});
await server.start();
app.use(express.json());
app.use(
'/graphql',
expressMiddleware(server, {
context: async ({ req, res }) => ({ req, res }),
})
);
await new Promise<void>((resolve) => {
httpSever.listen({ port: PORT }, resolve);
});
console.log(`server is up and running at http://localhost:{PORT}`);
}
main().catch(async (error) => {
console.error(error);
await prismaClient.$disconnect();
process.exit(1);
});
⑤ Create/types/graphql.ts
⑥ Edit make-todo/make-todo.resolvers.ts
import crypto from 'crypto';
import { Resolvers } from '../../../_generated_/graphql.js';
import { MyContext } from '../../../types/graphql.js';
export const resolvers: Resolvers<MyContext> = {
Mutation: {
makeTodo: async (_, { makeTodoInput }, { prismaClient }, info) => {
const newTodo = await prismaClient.todo.create({
date: {
title: makeTodoInput.title,
},
});
return {
todo: {
...newTodo,
updatedAt: newTodo.updatedAt.toISOString(),
createdAt: newTodo.createdAt.toISOString(),
},
};
},
},
};
⑦ Add code to backend/src/package.json
//省略
"scripts": {
//省略
"gen": "graphql-codegen --config codegen.yml",
"gen:db": "prisma migrate dev --name",
"gui:db": "prisma studio",
"cpgql": "copyfiles -u 1 src/**/*.graphql ./dist "
},
⑧ Create migration file in backend
npm run gen:db -- fix-type-todo-table
npm run gui:db
⑨ Create get-todos.graphql, get-todos.resolvers.ts in get-todos folder
type GetTodosResponse {
getTodos: [Todo]
}
type Query {
getTodos: GetTodosResponse
}
npm run cpgql
npm run gen:gql
⑩ Create remove-todo.graphql,remove-todo.resolvers.ts in remove-todo folder
input UpdateTodoInput {
todoId: String!
title: String
isCompleted: Boolean
}
type UpdateTodoResponse {
todo: Todo!
}
type Mutation {
updateTodo(updateTodoInput: UpdateTodoInput!): UpdateTodoResponse!
}
npm run cpgql
npm run gen:gql
import { GraphQLError } from 'graphql';
import { Resolvers } from '../../../_generated_/graphql.js';
import { MyContext } from '../../../types/graphql.js';
export const resolvers: Resolvers<MyContext> = {
Mutation: {
removeTodo: async (_, { removeTodoInput }, { prismaClient }, info) => {
const existingTodo = await prismaClient.todo.findUnique({
where: {
id: removeTodoInput.todoId,
},
});
if (!existingTodo) {
throw new GraphQLError('Not found');
}
await prismaClient.todo.delete({
where: {
id: existingTodo.id,
},
});
return {
todo: {
...existingTodo,
updatedAt: existingTodo.updatedAt.toISOString(),
createdAt: existingTodo.createdAt.toISOString(),
},
};
},
},
};
⑩ Create update-todo.graphql,update-todo.resolvers.ts in update-todo folder
input UpdateTodoInput {
todoId: String!
title: String
isCompleted: Boolean
}
type UpdateTodoResponse {
todo: Todo!
}
type Mutation {
updateTodo(updateTodoInput: UpdateTodoInput!): UpdateTodoResponse!
}
import { GraphQLError } from 'graphql';
import { Resolvers } from '../../../_generated_/graphql.js';
import { MyContext } from '../../../types/graphql.js';
import { title } from 'process';
export const resolvers: Resolvers<MyContext> = {
Mutation: {
updateTodo: async (_, { updateTodoInput }, { prismaClient }, info) => {
const existingTodo = await prismaClient.todo.findUnique({
where: {
id: updateTodoInput.todoId,
},
});
if (!existingTodo) {
throw new GraphQLError('Not found');
}
if (typeof updateTodoInput.title === 'string') {
existingTodo.title = updateTodoInput.title;
}
if (typeof updateTodoInput.isCompleted === 'boolean') {
existingTodo.isCompleted = updateTodoInput.isCompleted;
}
await prismaClient.todo.update({
where: {
id: existingTodo.id,
},
date: {
title: existingTodo.title,
isCompleted: existingTodo.isCompleted,
},
});
return {
todo: {
...existingTodo,
updatedAt: existingTodo.updatedAt.toISOString(),
createdAt: existingTodo.createdAt.toISOString(),
},
};
},
},
};
⑪ Create get-todo.graphql,get-todo.resolvers.ts in get-todo folder
input GetTodoInput {
todoId: String!
}
type GetTodoRespose {
todo: Todo!
}
type Query {
getTodo(GetTodo: GetTodoInput!): GetTodoRespose!
}
import { Resolvers } from '../../../_generated_/graphql.js';
import { MyContext } from '../../../types/graphql.js';
export const resolvers: Resolvers<MyContext> = {
Query: {
getTodo: async (_, { getTodoInput }, { prismaClient }, info) => {
const existingTodo = await prismaClient.todo.findUnique({
where: {
id: getTodoInput.todoId,
},
});
if (!existingTodo) {
throw new GraphQLError('Not found');
}
return {
todos: {
...existingTodo,
updatedAt: existingTodo.updatedAt.toISOString(),
createdAt: existingTodo.createdAt.toISOString(),
},
};
},
},
};
6 - Adding DateTime Scalar
① Create scalars/datetime folder and datetime.graphql, datetime.resolvers.ts in root folder
② Adding DateTime Scalar
overwrite: true
schema: 'http://localhost:5555/graphql'
generates:
src/__generated__/graphql.ts:
config:
scalars:
DateTime: 'Date'
plugins:
- 'typescript'
- 'typescript-resolvers'
npm i -E graphql-scalars
7- Implementation of Tailwind CSS and Apollo Client
① Install Tailwind CSS on the frontend
npm i -DE tailwindcss postcss autoprefixer
npx tailwindcss init -p
② Edit tailwind.config.js
/** @type {import('tailwindcss').Config} */
module.exports = {
content: ['index.html', 'src/**/:/{js,ts,jsx,tsx}'],
theme: {
extend: {},
},
plugins: [],
};
③ Edit frontend/src/index.css
@tailwind base;
@tailwind components;
@tailwind utilities;
④ Edit frontend/src/App.tsx
⑤ Share resources across origins in backend
npm i -E cors
npm i -ED @types/cors
⑥ Edit backend/src/index.ts
//omission
import cors from 'cors';
//omission
app.use(
cors({
origin: 'http://localhost:5173',
})
);
⑦ Install to frontend
npm i --save-dev @types/react
npm i react-dom
npm i vite
npm i @types/vite
npm i @vitejs/plugin-react
npm i -E graphql @apollo/client
npm i -DE @graphql-codegen/cli
⑧ Set up apollo/client
declare module 'react-dom/client';
import React from 'react';
import ReactDOM from 'react-dom/client';
import App from './App.tsx';
import './index.css';
import { ApolloClient, ApolloProvider, InMemoryCache } from '@apollo/client';
const apolloClient = new ApolloClient({
uri: 'http://localhost:5555/graphql', // Adjust the GraphQL endpoint URL as needed
cache: new InMemoryCache(),
});
ReactDOM.createRoot(document.getElementById('root')!).render(
<React.StrictMode>
<ApolloProvider client={apolloClient}>
<App />
</ApolloProvider>
</React.StrictMode>
);
⑨ Edit frontend/src/App.tsx
⑩ Automate type specification in frontend
npm i -ED @graphql-codegen/cli
mkdir src/_generated_
mkdir src/graphql
npx graphql-code-generator init
npm i -DE @graphql-codegen/typescript-react-apollo @graphql-codegen/typescript @graphql-codegen/typescript-operations
⑪ Edit frontend/codegen.yml
overwrite: true
schema: 'http://localhost:5555/graphql'
documents: 'src/graphql/**/*.graphql'
generates:
src/__generated__/graphql.ts:
config:
scalars:
DateTime: 'Date'
plugins: ['typescript-react-apollo', 'typescript', 'typescript-operations']
⑫ Create todos/queries/get-todo.graphql in graphql file
const getTodoQuery = gql`
query Todos {
getTodos {
todos {
id
title
isCompleted
createAt
updateAt
}
}
}
`;
npm run gen
⑬ Create graphql.tsx in generated file
import { gql } from '@apollo/client';
import * as Apollo from '@apollo/client';
export type Maybe<T> = T | null;
export type InputMaybe<T> = Maybe<T>;
export type Exact<T extends { [key: string]: unknown }> = { [K in keyof T]: T[K] };
export type MakeOptional<T, K extends keyof T> = Omit<T, K> & { [SubKey in K]?: Maybe<T[SubKey]> };
export type MakeMaybe<T, K extends keyof T> = Omit<T, K> & { [SubKey in K]: Maybe<T[SubKey]> };
const defaultOptions = {} as const;
/** All built-in and custom scalars, mapped to their actual values */
export type Scalars = {
ID: string;
String: string;
Boolean: boolean;
Int: number;
Float: number;
Void: void;
};
export type CheckAuthResponse = {
__typename?: 'CheckAuthResponse';
user?: Maybe<User>;
};
export type ConfirmEmailInput = {
token: Scalars['String'];
};
export type ConfirmEmailResponse = {
__typename?: 'ConfirmEmailResponse';
user?: Maybe<User>;
};
export type LoginInput = {
email: Scalars['String'];
password: Scalars['String'];
};
export type LoginResponse = {
__typename?: 'LoginResponse';
user?: Maybe<User>;
};
export type Mutation = {
__typename?: 'Mutation';
confirmEmail?: Maybe<ConfirmEmailResponse>;
login?: Maybe<LoginResponse>;
logout?: Maybe<Scalars['Void']>;
register?: Maybe<RegisterResponse>;
};
export type MutationConfirmEmailArgs = {
confirmEmailInput: ConfirmEmailInput;
};
export type MutationLoginArgs = {
loginInput: LoginInput;
};
export type MutationRegisterArgs = {
registerInput: RegisterInput;
};
export type Query = {
__typename?: 'Query';
checkAuth?: Maybe<CheckAuthResponse>;
health?: Maybe<Scalars['Boolean']>;
};
export type RegisterInput = {
email: Scalars['String'];
password: Scalars['String'];
};
export type RegisterResponse = {
__typename?: 'RegisterResponse';
user?: Maybe<User>;
};
export type User = {
__typename?: 'User';
createdAt?: Maybe<Scalars['String']>;
email?: Maybe<Scalars['String']>;
id?: Maybe<Scalars['String']>;
updatedAt?: Maybe<Scalars['String']>;
};
export type ConfirmEmailMutationVariables = Exact<{
confirmEmailInput: ConfirmEmailInput;
}>;
export type ConfirmEmailMutation = { __typename?: 'Mutation', confirmEmail?: { __typename?: 'ConfirmEmailResponse', user?: { __typename?: 'User', id?: string | null, email?: string | null, createdAt?: string | null, updatedAt?: string | null } | null } | null };
export type LoginMutationVariables = Exact<{
loginInput: LoginInput;
}>;
export type LoginMutation = { __typename?: 'Mutation', login?: { __typename?: 'LoginResponse', user?: { __typename?: 'User', id?: string | null, email?: string | null, createdAt?: string | null, updatedAt?: string | null } | null } | null };
export type LogoutMutationVariables = Exact<{ [key: string]: never; }>;
export type LogoutMutation = { __typename?: 'Mutation', logout?: void | null };
export type RegisterMutationVariables = Exact<{
registerInput: RegisterInput;
}>;
export type RegisterMutation = { __typename?: 'Mutation', register?: { __typename?: 'RegisterResponse', user?: { __typename?: 'User', id?: string | null, email?: string | null, createdAt?: string | null, updatedAt?: string | null } | null } | null };
export type CheckAuthQueryVariables = Exact<{ [key: string]: never; }>;
export type CheckAuthQuery = { __typename?: 'Query', checkAuth?: { __typename?: 'CheckAuthResponse', user?: { __typename?: 'User', id?: string | null, email?: string | null, updatedAt?: string | null, createdAt?: string | null } | null } | null };
export const ConfirmEmailDocument = gql`
mutation ConfirmEmail($confirmEmailInput: ConfirmEmailInput!) {
confirmEmail(confirmEmailInput: $confirmEmailInput) {
user {
id
email
createdAt
updatedAt
}
}
}
`;
export type ConfirmEmailMutationFn = Apollo.MutationFunction<ConfirmEmailMutation, ConfirmEmailMutationVariables>;
/**
* __useConfirmEmailMutation__
*
* To run a mutation, you first call `useConfirmEmailMutation` within a React component and pass it any options that fit your needs.
* When your component renders, `useConfirmEmailMutation` returns a tuple that includes:
* - A mutate function that you can call at any time to execute the mutation
* - An object with fields that represent the current status of the mutation's execution
*
* @param baseOptions options that will be passed into the mutation, supported options are listed on: https://www.apollographql.com/docs/react/api/react-hooks/#options-2;
*
* @example
* const [confirmEmailMutation, { data, loading, error }] = useConfirmEmailMutation({
* variables: {
* confirmEmailInput: // value for 'confirmEmailInput'
* },
* });
*/
export function useConfirmEmailMutation(baseOptions?: Apollo.MutationHookOptions<ConfirmEmailMutation, ConfirmEmailMutationVariables>) {
const options = {...defaultOptions, ...baseOptions}
return Apollo.useMutation<ConfirmEmailMutation, ConfirmEmailMutationVariables>(ConfirmEmailDocument, options);
}
export type ConfirmEmailMutationHookResult = ReturnType<typeof useConfirmEmailMutation>;
export type ConfirmEmailMutationResult = Apollo.MutationResult<ConfirmEmailMutation>;
export type ConfirmEmailMutationOptions = Apollo.BaseMutationOptions<ConfirmEmailMutation, ConfirmEmailMutationVariables>;
export const LoginDocument = gql`
mutation Login($loginInput: LoginInput!) {
login(loginInput: $loginInput) {
user {
id
email
createdAt
updatedAt
}
}
}
`;
export type LoginMutationFn = Apollo.MutationFunction<LoginMutation, LoginMutationVariables>;
/**
* __useLoginMutation__
*
* To run a mutation, you first call `useLoginMutation` within a React component and pass it any options that fit your needs.
* When your component renders, `useLoginMutation` returns a tuple that includes:
* - A mutate function that you can call at any time to execute the mutation
* - An object with fields that represent the current status of the mutation's execution
*
* @param baseOptions options that will be passed into the mutation, supported options are listed on: https://www.apollographql.com/docs/react/api/react-hooks/#options-2;
*
* @example
* const [loginMutation, { data, loading, error }] = useLoginMutation({
* variables: {
* loginInput: // value for 'loginInput'
* },
* });
*/
export function useLoginMutation(baseOptions?: Apollo.MutationHookOptions<LoginMutation, LoginMutationVariables>) {
const options = {...defaultOptions, ...baseOptions}
return Apollo.useMutation<LoginMutation, LoginMutationVariables>(LoginDocument, options);
}
export type LoginMutationHookResult = ReturnType<typeof useLoginMutation>;
export type LoginMutationResult = Apollo.MutationResult<LoginMutation>;
export type LoginMutationOptions = Apollo.BaseMutationOptions<LoginMutation, LoginMutationVariables>;
export const LogoutDocument = gql`
mutation Logout {
logout
}
`;
export type LogoutMutationFn = Apollo.MutationFunction<LogoutMutation, LogoutMutationVariables>;
/**
* __useLogoutMutation__
*
* To run a mutation, you first call `useLogoutMutation` within a React component and pass it any options that fit your needs.
* When your component renders, `useLogoutMutation` returns a tuple that includes:
* - A mutate function that you can call at any time to execute the mutation
* - An object with fields that represent the current status of the mutation's execution
*
* @param baseOptions options that will be passed into the mutation, supported options are listed on: https://www.apollographql.com/docs/react/api/react-hooks/#options-2;
*
* @example
* const [logoutMutation, { data, loading, error }] = useLogoutMutation({
* variables: {
* },
* });
*/
export function useLogoutMutation(baseOptions?: Apollo.MutationHookOptions<LogoutMutation, LogoutMutationVariables>) {
const options = {...defaultOptions, ...baseOptions}
return Apollo.useMutation<LogoutMutation, LogoutMutationVariables>(LogoutDocument, options);
}
export type LogoutMutationHookResult = ReturnType<typeof useLogoutMutation>;
export type LogoutMutationResult = Apollo.MutationResult<LogoutMutation>;
export type LogoutMutationOptions = Apollo.BaseMutationOptions<LogoutMutation, LogoutMutationVariables>;
export const RegisterDocument = gql`
mutation Register($registerInput: RegisterInput!) {
register(registerInput: $registerInput) {
user {
id
email
createdAt
updatedAt
}
}
}
`;
export type RegisterMutationFn = Apollo.MutationFunction<RegisterMutation, RegisterMutationVariables>;
/**
* __useRegisterMutation__
*
* To run a mutation, you first call `useRegisterMutation` within a React component and pass it any options that fit your needs.
* When your component renders, `useRegisterMutation` returns a tuple that includes:
* - A mutate function that you can call at any time to execute the mutation
* - An object with fields that represent the current status of the mutation's execution
*
* @param baseOptions options that will be passed into the mutation, supported options are listed on: https://www.apollographql.com/docs/react/api/react-hooks/#options-2;
*
* @example
* const [registerMutation, { data, loading, error }] = useRegisterMutation({
* variables: {
* registerInput: // value for 'registerInput'
* },
* });
*/
export function useRegisterMutation(baseOptions?: Apollo.MutationHookOptions<RegisterMutation, RegisterMutationVariables>) {
const options = {...defaultOptions, ...baseOptions}
return Apollo.useMutation<RegisterMutation, RegisterMutationVariables>(RegisterDocument, options);
}
export type RegisterMutationHookResult = ReturnType<typeof useRegisterMutation>;
export type RegisterMutationResult = Apollo.MutationResult<RegisterMutation>;
export type RegisterMutationOptions = Apollo.BaseMutationOptions<RegisterMutation, RegisterMutationVariables>;
export const CheckAuthDocument = gql`
query CheckAuth {
checkAuth {
user {
id
email
updatedAt
createdAt
}
}
}
`;
/**
* __useCheckAuthQuery__
*
* To run a query within a React component, call `useCheckAuthQuery` and pass it any options that fit your needs.
* When your component renders, `useCheckAuthQuery` returns an object from Apollo Client that contains loading, error, and data properties
* you can use to render your UI.
*
* @param baseOptions options that will be passed into the query, supported options are listed on: https://www.apollographql.com/docs/react/api/react-hooks/#options;
*
* @example
* const { data, loading, error } = useCheckAuthQuery({
* variables: {
* },
* });
*/
export function useCheckAuthQuery(baseOptions?: Apollo.QueryHookOptions<CheckAuthQuery, CheckAuthQueryVariables>) {
const options = {...defaultOptions, ...baseOptions}
return Apollo.useQuery<CheckAuthQuery, CheckAuthQueryVariables>(CheckAuthDocument, options);
}
export function useCheckAuthLazyQuery(baseOptions?: Apollo.LazyQueryHookOptions<CheckAuthQuery, CheckAuthQueryVariables>) {
const options = {...defaultOptions, ...baseOptions}
return Apollo.useLazyQuery<CheckAuthQuery, CheckAuthQueryVariables>(CheckAuthDocument, options);
}
export type CheckAuthQueryHookResult = ReturnType<typeof useCheckAuthQuery>;
export type CheckAuthLazyQueryHookResult = ReturnType<typeof useCheckAuthLazyQuery>;
export type CheckAuthQueryResult = Apollo.QueryResult<CheckAuthQuery, CheckAuthQueryVariables>;
Reference site
【TypeScript & GraphQL】で Fullstack Web Application開発 #1 - プロジェクトセットアップ
【TypeScript & GraphQL】で Fullstack Web Application開発 #2 - ミニマムなApollo serverの立ち上げ
【TypeScript & GraphQL】で Fullstack Web Application開発 #3 - Graphql コードジェネレーターの追加
【TypeScript & GraphQL】で Fullstack Web Application開発 #4 - TypeDefsとResolversの自動インポート
【TypeScript & GraphQL】で Fullstack Web Application開発 #5 - Prismaの準備&TodoCRUDの実装
【TypeScript & GraphQL】で Fullstack Web Application開発 #6 - DateTime Scalarの追加
【TypeScript & GraphQL】で Fullstack Web Application開発 #7- Tailwind CSSとApollo Clientの実装