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 demo-role.js
npx sequelize-cli db:seed --seed demo-users.js
npx sequelize-cli db:seed --seed demo-permissions.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
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_priority'], value: job.job_priority },
{ name: ['taxonomies', 'job_status'], value: job.job_status },
// metadata
{ 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,
},
],
},
],
},
];