Getting started with Next.js
This guide will walk you through setting up a Next.js application with @mercury-js/core
, enabling you to quickly build a robust and secure API backend.
Project Structure
Here's a recommended project structure:
your-project
├── src
│ ├── app
│ │ └── api
│ │ └── graphql
│ │ └── route.ts
│ ├── models
│ │ ├── [your-model].ts
│ │ └── index.ts
│ ├── profiles
│ │ ├── [your-profile].ts
│ │ └── index.ts
│ └── hooks
│ ├── [your-hook].ts
│ └── index.ts
├── next.config.js
├── tsconfig.json
├── package.json
└── ...
- app: Contains your Next.js routes, including your API endpoints.
- api: Houses your API routes.
- models: Contains your Mongoose models.
- profiles: Stores your access control profiles.
- hooks: Holds pre- and post-event hooks for your models.
- next.config.js: Configures your Next.js application.
- tsconfig.json: Typescript configuration file.
- package.json: Contains project dependencies and scripts.
Setting up the server
-
Install
@mercury-js/core
:npm install @mercury-js/core
-
Install Other Dependencies:
npm install @as-integrations/next @apollo/server @graphql-tools/schema graphql-middleware
-
Create a Route (
app/api/graphql/route.ts
):import { startServerAndCreateNextHandler } from '@as-integrations/next';
import mercury from '@mercury-js/core';
import { ApolloServer } from '@apollo/server';
import { makeExecutableSchema } from '@graphql-tools/schema';
import { applyMiddleware } from 'graphql-middleware';
import '../../../models'; // Import your models
import '../../../profiles'; // Import your profiles
import '../../../hooks'; // Import your hooks
// Connect to your MongoDB database
mercury.connect(process.env.DB_URL || 'mongodb://localhost:27017/mercury');
// Add additional GraphQL typedefs and resolvers (optional)
mercury.addGraphqlSchema(
`
type Query {
hello: String
}
`,
{
Query: {
hello: (root: any, args: any, ctx: any, resolveInfo: any) => {
return 'Hello World!';
},
},
}
);
// Create the GraphQL schema
const schema = applyMiddleware(
makeExecutableSchema({
typeDefs: mercury.typeDefs,
resolvers: mercury.resolvers as unknown as IResolvers<
any,
GraphQLResolveInfo
>[],
})
);
// Initialize Apollo Server
const server = new ApolloServer({
schema,
});
// Create Next.js handler
const handler = startServerAndCreateNextHandler(server, {
context: async (req, res) => ({
...req,
user: {
id: '1', // Example user ID
profile: 'Admin', // Example user profile
},
}),
});
export async function GET(request: any) {
return handler(request);
}
export async function POST(request: any) {
return handler(request);
}
Creating Models
-
Create Model Files (
models/[your-model].ts
):// models/User.model.ts
import mercury from '@mercury-js/core';
export const User = mercury.createModel(
'User',
{
name: {
type: 'string',
},
account: {
type: 'relationship',
ref: 'Account',
},
password: {
type: 'string',
bcrypt: true,
},
},
{}
);
// models/Account.model.ts
import mercury from '@mercury-js/core';
export const AccountSchema = {
name: {
type: 'string',
},
user: {
type: 'relationship',
ref: 'User',
},
};
export const Account = mercury.createModel('Account', AccountSchema, {});Note: The
password
field in theUser
model will automatically be encrypted and stored in the database. For more details, refer to the bcrypt field section in the model documentation. -
Export Models (
models/index.ts
):// models/index.ts
export { User } from './User.model';
export { Account } from './Account.model';
Setting Up Profiles
-
Create Profile Files (
profiles/[your-profile].ts
):// profiles/Admin.profile.ts
import mercury from '@mercury-js/core';
const rules = [
{
modelName: 'User',
access: {
create: true,
read: true,
update: true,
delete: true,
},
},
{
modelName: 'Account',
access: {
create: true,
read: true,
update: true,
delete: true,
},
},
];
export const AdminProfile = mercury.createProfile('Admin', rules);
// profiles/User.profile.ts
import mercury from '@mercury-js/core';
const rules = [
{
modelName: 'User',
access: {
create: false,
read: true,
update: false,
delete: false,
},
},
{
modelName: 'Account',
access: {
create: false,
read: true,
update: false,
delete: false,
},
fieldLevelAccess: true,
fields: {
name: {
read: false,
},
},
},
];
export const UserProfile = mercury.createProfile('User', rules); -
Export Profiles (
profiles/index.ts
):// profiles/index.ts
export { AdminProfile } from './Admin.profile';
export { UserProfile } from './User.profile';
Using Hooks
-
Create Hook Files (
hooks/[your-hook].ts
):// hooks/User.hook.ts
import { hook } from '@mercury-js/core';
hook.before('CREATE_USER_RECORD', async function (this: any) {
// Modify data before create
this.data.name = 'Test 1';
});
hook.after('CREATE_USER_RECORD', async function (this: any, args: any) {
console.log('AFTER CREATE hook', this);
}); -
Export Hooks (
hooks/index.ts
):// hooks/index.ts
import './User.hook';
Running the Server
-
Start the Development Server:
npm run dev
Now, you have a Next.js application with a secure, efficient, and scalable API backend powered by @mercury-js/core
. You can access your GraphQL API by making requests to your endpoint, for example:
http://localhost:3000/api/graphql
This structure can be modified and expanded to suit your specific needs, allowing you to build complex applications with ease and security using @mercury-js/core
.