Set up Apollo client with Nextjs and Apollo server GraphQL into single Express
Make sure you have Node.js 13+ as specified in package.json "engines" object.
yarn install
yarn dev
Goto http://localhost:3001/graphql
to generate database structure
Go to graphql
folder and run command line
npx sequelize-cli db:seed --seed 20200822034804-demo-role.js
npx sequelize-cli db:seed --seed 20200124071616-demo-users.js
Goto http://localhost:3001/api/auth/signin
input Email to signin
Open http://localhost:3001
to Enjoy!
Goto http://localhost:3001/admin/users
to manage users
DELETE from jobmeta;
DELETE from jobterms;
DELETE from jobs;
UPDATE usermeta as u SET u.value='10000000', u.data='10000000' WHERE u.key='account_money';
Auto sync database
const server = new ApolloServer({
...// Sync database
sequelize.sync(),
})
Create User
mutation{
createUser(data:{name:"Admin", email:"[email protected]", password: "1"}){
id
name
jwt
}
}
Login user
query {
loginUser(email:"[email protected]", password:"1") {
name
}
}
Query Role
query {
getRole(where:{id:1}){
id,
name
}
}
Restart graphql server at http://localhoast:3001/graphql
Go to packages/graphql run
yarn generate
Copy graphql.schema.json
to client/services/graphql.schema.json
Note documents must start by a query
Define virtual columns at model.ts
{
@Column(DataType.VIRTUAL)
link: string;
}
Must be include metadata
at type FooModel
type Foo {
metadata: [FooMeta]
fooMeta1,
fooMeta2,
...
}
type FooMeta {
foo: Foo
}
type FooMetaInput {
foo_id
key
value
}
Define FooMeta, FooMetaInput
metadata: [FooMeta]
before function
findOptions.include = [{ model: FooMeta }]
after function for a líst foo
const rows = foos.map((u) => metadataToField(u, 'metadata'))
after function for a foo
const transferData = metadataToField(user, 'metadata')
return transferData
Create or update a job
// Update taxonomies
if (job && taxonomies) {
const terms = taxonomies.map((termId) => ({
term_taxonomy_id: termId,
ref_id: job.id,
}))
await JobTerm.bulkCreate(terms)
}
// Metadata
if (job && metadata) {
const meta = metadata.map((x) => ({
...x,
job_id: job.id,
}))
await JobMeta.bulkCreate(meta)
}
findOptions.where = { id: job.id }
return findOptions
Add metadata
or taxonomies
at field
<Form.Item
name={['job', 'dueDate']}
label={t('jobCreateform.label.dueDate')}
>
<DatePicker />
</Form.Item>
<Form.Item
name={['metadata', 'link']}
label={t('jobCreateform.label.link')}
>
<Input type="link" />
</Form.Item>
<Form.Item
name={['taxonomies', 'job_status']}
label={t('jobCreateform.label.status')}
>
<ComboBoxTaxonomy type={TaxonomyType.Job_Status} />
</Form.Item>
at submit method, pass metadata
and taxonomies
upsertJob({
variables: {
job,
metadata,
taxonomies,
},
})
load detail
const formSetFields = (job) => {
form.setFields([
// job
{ name: ['job', 'title'], value: job.title },
{ name: ['job', 'link'], value: job.link },
{ name: ['job', 'description'], value: job.description },
{ name: ['job', 'publishDate'], value: job.publishDate },
{ name: ['job', 'dueDate'], value: job.image },
// taxonomies
{ name: ['taxonomies', 'job_status'], value: job.job_status },
// metadata
{ name: ['metadata', 'priority'], value: job.priority },
{ name: ['metadata', 'link'], value: job.link },
])
}
Follow below, must have ForeignKey for TermTaxnomy, Foo
export class JobTerm extends Model<JobTerm> {
@BelongsTo(() => TermTaxonomy)
termTaxonomy: TermTaxonomy
@ForeignKey(() => TermTaxonomy)
@Column
term_taxonomy_id: number
@Column
order: number
// job
@Column
@ForeignKey(() => Job) // only change Job
ref_id: number
@BelongsTo(() => Job) // only change Job
job: Job
}
Follow below, must have termTaxnomies
field
type JobTerm {
...
termTaxonomies: TermTaxonomy
}
findOptions.include = [
{ model: JobMeta },
{
model: JobTerm, // FooTerm
require: true,
include: [
{
model: TermTaxonomy,
where: { taxonomy: ['job_priority', 'job_status'] }, // all of taxonomies fields
require: true,
include: [
{
model: Term,
require: true,
},
],
},
],
},
]