Skip to content

Commit aa9f558

Browse files
committed
8c start
1 parent 182bbfa commit aa9f558

File tree

2 files changed

+52
-27
lines changed

2 files changed

+52
-27
lines changed

src/content/8/en/part8c.md

Lines changed: 24 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -11,10 +11,10 @@ We will now add user management to our application, but let's first start using
1111

1212
### Mongoose and Apollo
1313

14-
Install mongoose:
14+
Install Mongoose and dotenv:
1515

1616
```bash
17-
npm install mongoose
17+
npm install mongoose dotenv
1818
```
1919

2020
We will imitate what we did in parts [3](/en/part3/saving_data_to_mongo_db) and [4](/en/part4/structure_of_backend_application_introduction_to_testing).
@@ -55,11 +55,12 @@ We also included a few validations. _required: true_, which makes sure that a va
5555
We can get the application to mostly work with the following changes:
5656

5757
```js
58-
const { ApolloServer, UserInputError, gql } = require('@apollo/server')
58+
// ...
5959
const mongoose = require('mongoose')
60+
mongoose.set('strictQuery', false)
6061
const Person = require('./models/person')
6162

62-
const MONGODB_URI = 'mongodb+srv://databaseurlhere'
63+
const MONGODB_URI = process.env.MONGODB_URI
6364

6465
console.log('connecting to', MONGODB_URI)
6566

@@ -121,9 +122,10 @@ allPersons: async (root, args) => {
121122
Apollo server waits for the promise to resolve, and returns the result. So Apollo works roughly like this:
122123

123124
```js
124-
Person.find({}).then( result => {
125-
// return the result
126-
})
125+
allPersons: async (root, args) => {
126+
const result = await Person.find({})
127+
return result
128+
}
127129
```
128130

129131
Let's complete the _allPersons_ resolver so it takes the optional parameter _phone_ into account:
@@ -155,7 +157,7 @@ Person.find({ phone: { $exists: false }})
155157

156158
### Validation
157159

158-
As well as in GraphQL, the input is now validated using the validations defined in the mongoose schema. For handling possible validation errors in the schema, we must add an error-handling _try/catch_ block to the _save_ method. When we end up in the catch, we throw a suitable exception:
160+
As well as in GraphQL, the input is now validated using the validations defined in the mongoose schema. For handling possible validation errors in the schema, we must add an error-handling _try/catch_ block to the _save_ method. When we end up in the catch, we throw a exception [GraphQLError](https://www.apollographql.com/docs/apollo-server/data/errors/#custom-errors) with error code :
159161

160162
```js
161163
Mutation: {
@@ -166,8 +168,12 @@ Mutation: {
166168
try {
167169
await person.save()
168170
} catch (error) {
169-
throw new UserInputError(error.message, {
170-
invalidArgs: args,
171+
throw new GraphQLError('Saving person failed', {
172+
extensions: {
173+
code: 'BAD_USER_INPUT',
174+
invalidArgs: args.name,
175+
error
176+
}
171177
})
172178
}
173179
// highlight-end
@@ -182,8 +188,12 @@ Mutation: {
182188
try {
183189
await person.save()
184190
} catch (error) {
185-
throw new UserInputError(error.message, {
186-
invalidArgs: args,
191+
throw new GraphQLError('Saving number failed', {
192+
extensions: {
193+
code: 'BAD_USER_INPUT',
194+
invalidArgs: args.name,
195+
error
196+
}
187197
})
188198
}
189199
// highlight-end
@@ -193,6 +203,8 @@ Mutation: {
193203
}
194204
```
195205

206+
We have also added the Mongoose error and the data that caused the error to the <i>extensions</i> object that is used to convey more info about the cause of the error to the caller.
207+
196208
The code of the backend can be found on [Github](https://github.com/fullstack-hy2020/graphql-phonebook-backend/tree/part8-4), branch <i>part8-4</i>.
197209

198210
### User and log in

src/content/8/fi/osa8c.md

Lines changed: 28 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -11,10 +11,10 @@ Laajennetaan sovellusta käyttäjänhallinnalla. Siirrytään kuitenkin ensin k
1111

1212
### Mongoose ja Apollo
1313

14-
Otetaan käyttöön Mongoose:
14+
Otetaan käyttöön Mongoose ja asennetaan samalla dotenv:
1515

1616
```bash
17-
npm install mongoose
17+
npm install mongoose dotenv
1818
```
1919

2020
Tehdään osien [3](/osa3/tietojen_tallettaminen_mongo_db_tietokantaan) ja [4](/osa4/sovelluksen_rakenne_ja_testauksen_alkeet) tapaa imitoiden.
@@ -54,11 +54,14 @@ Mukana on myös muutama validointi. Arvon olemassaolon takaava _required: true_
5454
Saamme sovelluksen jo suurilta osin toimimaan seuraavilla muutoksilla:
5555

5656
```js
57-
const { ApolloServer, UserInputError, gql } = require('apollo-server')
57+
// ...
58+
59+
5860
const mongoose = require('mongoose')
61+
mongoose.set('strictQuery', false)
5962
const Person = require('./models/person')
6063

61-
const MONGODB_URI = 'mongodb+srv://databaseurlhere'
64+
const MONGODB_URI = process.env.MONGODB_URI
6265

6366
console.log('connecting to', MONGODB_URI)
6467

@@ -70,7 +73,7 @@ mongoose.connect(MONGODB_URI)
7073
console.log('error connection to MongoDB:', error.message)
7174
})
7275

73-
const typeDefs = gql`
76+
const typeDefs = `
7477
...
7578
`
7679

@@ -109,21 +112,21 @@ Muutokset ovat melko suoraviivaisia. Huomio kiinnittyy pariin seikkaan. Kuten mu
109112

110113
Toinen huomionarvoinen seikka on se, että resolverifunktiot palauttavat nyt <i>promisen</i>, aiemminhan ne palauttivat aina normaaleja oliota. Kun resolveri palauttaa promisen, Apollo server [osaa lähettää vastaukseksi](https://www.apollographql.com/docs/apollo-server/data/resolvers/#return-values) sen arvon mihin promise resolvoituu.
111114

112-
113115
Eli esimerkiksi jos seuraava resolverifunktio suoritetaan,
114116

115117
```js
116118
allPersons: async (root, args) => {
117119
return Person.find({})
118-
},
120+
}
119121
```
120122

121123
odottaa Apollo server promisen valmistumista ja lähettää promisen vastauksen kyselyn tekijälle. Apollo toimii siis suunnilleen seuraavasti:
122124

123125
```js
124-
Person.find({}).then( result => {
125-
// palautetaan kyselyn tuloksena result
126-
})
126+
allPersons: async (root, args) => {
127+
const result = await Person.find({})
128+
return result
129+
}
127130
```
128131

129132
Täydennetään vielä resolveri _allPersons_ ottamaan huomioon optionaalinen filtterinä toimiva parametri _phone_:
@@ -155,7 +158,7 @@ Person.find({ phone: { $exists: false }})
155158

156159
### Validoinnit
157160

158-
GraphQL:n lisäksi syötteet validoidaan nyt Mongoose-skeemassa määriteltyjä validointeja käyttäen. Skeemassa olevien validointivirheiden varalta _save_-metodeille täytyy lisätä virheen käsittelevä _try/catch_-lohko. Heitetään catchiin jouduttaessa vastaukseksi sopiva poikkeus, joka on tällä kertaa [UserInputError](https://www.apollographql.com/docs/apollo-server/data/errors/):
161+
GraphQL:n lisäksi syötteet validoidaan nyt Mongoose-skeemassa määriteltyjä validointeja käyttäen. Skeemassa olevien validointivirheiden varalta _save_-metodeille täytyy lisätä virheen käsittelevä _try/catch_-lohko. Heitetään catchiin jouduttaessa vastaukseksi [virhekoodilla](https://www.apollographql.com/docs/apollo-server/data/errors/#built-in-error-codes) *BAD\_USER\_INPUT* varustetu poikkeus [GraphQLError](https://www.apollographql.com/docs/apollo-server/data/errors/#custom-errors):
159162

160163
```js
161164
Mutation: {
@@ -166,8 +169,12 @@ Mutation: {
166169
try {
167170
await person.save()
168171
} catch (error) {
169-
throw new UserInputError(error.message, {
170-
invalidArgs: args,
172+
throw new GraphQLError('Saving person failed', {
173+
extensions: {
174+
code: 'BAD_USER_INPUT',
175+
invalidArgs: args.name,
176+
error
177+
}
171178
})
172179
}
173180
// highlight-end
@@ -182,8 +189,12 @@ Mutation: {
182189
try {
183190
await person.save()
184191
} catch (error) {
185-
throw new UserInputError(error.message, {
186-
invalidArgs: args,
192+
throw new GraphQLError('Saving number failed', {
193+
extensions: {
194+
code: 'BAD_USER_INPUT',
195+
invalidArgs: args.name,
196+
error
197+
}
187198
})
188199
}
189200
// highlight-end
@@ -193,6 +204,8 @@ Mutation: {
193204
}
194205
```
195206

207+
Mongoosen virheen tiedot ja ongelman aiheuttanut data on nyt liitetty poikkeuksen konfiguraatio-olioon <i>extensions</i>, näin ne saadaan välitettyä kutsujalle.
208+
196209
Backendin koodi on kokonaisuudessaan [GitHubissa](https://github.com/fullstack-hy2020/graphql-phonebook-backend/tree/part8-4), branchissa <i>part8-4</i>.
197210

198211
### Käyttäjä ja kirjautuminen

0 commit comments

Comments
 (0)