markdown 创建Apollo Graphql Schema和CRUD
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了markdown 创建Apollo Graphql Schema和CRUD相关的知识,希望对你有一定的参考价值。
datamodel.prisma
# practice
## not using optional property
errorless 프로그래밍 for apollo graphql
datamodel.prisma에서 default value를 설정하는것은 seeding할때 편하게 하기 위해서이다
또한 설령 optional한 value일지라도 default value를 설정해 두는것이 errorless한 프로그래밍이 된다
frontend에서 설정한 값이 누락되지 않고 뮤테이션에 전달되기 위해서라도 schema.graphql(backend의 client)에서 !(필수) 를 설정해 두는것이 errorless한 프로그래밍이다
이것은
playground에서 모든 property들을 setting해야 하는 번거로움이 있지만 그렇다고 하더라도 그런식으로 해야지 error를 잡을 수 있다
## proprties
### Use createdWhen instead of createdAt
```gql
createdWhen: DateTime!
```
> createdAt is readonly so I can't change its value when I need to change it. that is why it is good to use `createdWhen` instead
### Use alias for better seeding and testing
```gql
alias: string @unique
```
when seeding
in seed.graphql
```
pogyowon1: createPogyowon(data: {
name: "Pogyowon1"
alias: "testPogyowon"
}){
id
}
...
testUser: createUser(data: {
email: "godon019@gmail.com"
name: "Gordon"
pogyowons: {
connect: [{
alias: "testPogyowon"
}]
}
}){
id
}
```
- **easier seeding** : it is easier to use `connect` with alias then using `id` to connect
that is because, `id` is be always different whenever create new seed, it isn't easy to manually connect.
- **easier on front-end testing** : same reason from above
datamodel.prisma
```gql
type Activity implements Reportable{
id: ID! @unique
createdWhen: DateTime!
category: String! @default(value: "활동")
tag: String! @default(value: "")
content: String! @default(value: "")
pogyowon: Pogyowon!
}
}
```
For Reportable
```
type Activity implements Reportable{
id: ID! @unique
createdWhen: DateTime!
category: String! @default(value: "활동")
```
For its own
```
tag: String! @default(value: "")
content: String! @default(value: "")
```
> it is good practice to use it as **non-optional** and initialize it with empty value
Essential (Common namespace as store)
```
pogyowon: Pogyowon!
```
---
seed.graphql
```gql
activity1: createActivity(data: {
pogyowon: { connect: {alias : "testPogyowon"}}
createdWhen: "2019-3-11T13:57:31.123Z"
content: "보살님들께 노래 불러드림"
}){
id
}
```
**connect store**
```gql
pogyowon: { connect: {alias : "testPogyowon"}}
```
**common date**
```gql
createdWhen: "2019-3-11T13:57:31.123Z"
```
---
in command line
```
prisma reset -f; prisma deploy; prisma seed;
```
> create `prisma-client` folder and files so that I can easily use it
---
schema.graphql
```gql
type Activity implements Reportable{
id: ID!
createdWhen: String!
category: String!
tag: String!
content: String!
pogyowon: Pogyowon!
}
```
---
create a file in `resolvers` folder with its name
resolvers/Activity.ts
```ts
export const Activity = {
pogyowon: ({id}, args, ctx: Context) =>{
return ctx.prisma.bosigeum({id}).pogyowon()
},
}
```
> scalar types can be omitted but, I have to manually write for custom types
---
# when typs is implemented from interface
if it is reportable type
add to reportables
resolvers/Query/reportables.ts
```ts
const warehousings = await ctx.prisma.warehousings(condition)
\!h const activities = await ctx.prisma.activities(condition)
\!h let merged = [...expenses, ...bulsageums, ...bosigeums, ...warehousings, ...activities]
merged.sort((a, b) => {
return Date.parse(a.createdWhen) - Date.parse(b.createdWhen)
})
return merged
}
\!h type ReportableWhereInput = ExpenseWhereInput | BulsageumWhereInput | BosigeumWhereInput | WarehousingWhereInput | ActivityWhereInput
```
---
reprotable.ts
```ts
export const Reportable = {
__resolveType: (reportable, ctx: Context, info) => {
const { category } = reportable
if(category === "불사금"){
return 'Bulsageum'
}
else if(category === "지출"){
return 'Expense'
}
else if(category === "보시금"){
return 'Bosigeum'
}
else if(category === "입고"){
return 'Warehousing'
}
return null
},
}
```
fragmentTypes.json
```js
{
"__schema": {
"types": [
{
"kind": "INTERFACE",
"name": "Reportable",
"possibleTypes": [
{
"name": "Bulsageum"
},
{
"name": "Expense"
},
{
"name": "Bosigeum"
},
{
"name": "Warehousing"
},
{
\!h "name": "Activity"
}
]
}
]
}
}
```
ReportableQuery/index.tsx
```tsx
... on Activity{
tag
content
}
```
```tsx
export interface IActivityQuery {
id: string,
category: string,
createdWhen: string,
tag: string,
content: string,
}
export type TReportable = IBulsageumFromReportableQuery | IBosigeumQuery | IExpenseQuery | IWarehousingQuery | IActivityQuery
```
ReportableView/index.tsx
```
export const isExpense = (rpt: TReportable) => rpt.category === "지출"
export const isBulsageum = (rpt: TReportable) => rpt.category === "불사금"
export const isBosigeum = (rpt: TReportable) => rpt.category === "보시금"
\!h export const isWarehousing = (rpt: TReportable) => rpt.category === "입고"
const _distribute = (reportable: TReportable) => {
if (isExpense(reportable)) { //CONSTANT
return <ExpenseView expense={reportable as IExpenseQuery} />
}
else if (isBosigeum(reportable)) {
return <ReportableBosigeumView bosigeum={reportable as IBosigeumQuery} />
}
else if (isBulsageum(reportable)) {
return <ReportableBulsageumView bulsageum={reportable as IBulsageumFromReportableQuery} />
}
else if(isWarehousing(reportable)){
return <WarehousingView warehousing={reportable as IWarehousingQuery} />
}
\!h else if(isActivity(reportable)){
return <ActivityView activity={reportable as IActivityQuery} />
}
throw new Error('Not proper Reportable category')
}
```
---
create View
components/activities/activity/View.tsx
```tsx
const ActivityView: React.FC<{ activity: IActivityQuery }> = ({ activity }) => {
const { id, createdWhen, category, content, tag, } = activity
return (
<Wrapper>
<CreatedWhen value={createdWhen} />
<Category>{category}</Category>
<Tag>{tag}</Tag>
<Content>{content}</Content>
</Wrapper>)
}
export default ActivityView
```
whether type or interface it is encouraged to use `I + name + detail`
```ts
export type IActivityQuery = {
readonly id: string,
readonly category: string,
createdWhen: string,
tag: string,
content: string,
}
interface IActivityMutationVariable {
pogyowonId?: string,
pogyowonAlias?: string,
createdWhen: string,
content: string,
tag: string,
}
```
later when refactoring I can search easily with `I + name`
# When adding list query
add resolvers/Query/file.ts
add code to schema.graphql -> type Query
add code to resolvers/Query/index.ts
# When add update or create mutation
add resolvers/Mutation/file.ts
add code to resolvers/Mutation/index.ts
以上是关于markdown 创建Apollo Graphql Schema和CRUD的主要内容,如果未能解决你的问题,请参考以下文章
markdown 修复NPM错误初始化Apollo GraphQL项目“未命名的项目”
React Native、GraphQL、Apollo - 如何创建批量插入突变
如何使用 apollo 客户端库创建带有角度参数的 graphql 查询