ChatGPT is like Google + Udemy on steroids. How this affects you?

The release of ChatGPT provoked another avalanche of “AI will replace developers” speculations with many people trying to generate a project from scratch using it. From my perspective, this is a pointless take on this matter. I would rather concentrate on the following idea and its consequences.

AI is a net for catching relevant information in the big ocean human knowledge.

AI can be thought of as a way to filter and organize vast amounts of information and knowledge, making it easier for people to find and access what they need. AI can help us make sense of complex and overwhelming data sets and extract valuable insights and knowledge from them.

At the moment systems like ChatGPT are bringing this capability to a whole new level by providing a human-friendly chat interface that is context aware. And context awareness is really what makes it stand out!!! I will follow up on this just a few lines later.

AI is like Google on steroids + Udemy

Just think of your usual way to write code in the language or framework you are not totally familiar with. It usually starts with these sources of inspiration:

  • official documentation
  • code samples and tutorials found Google
  • StackOverflow
  • online courses

And your role here is usually to cherry-pick relevant bits of information and put them in your project in the proper places.

And this is the place where context-aware ChatGPT is replacing you. It is aware of all this information and it can deliver exactly what you need based on your progress with your work. We as humans can’t always express ourselves exactly in one go. We usually start with a simple question and make our requests more complex as we progress. And sometimes we need to go back on our work and improve something we’ve already done. This is where context awareness really shines.

To demonstrate my thoughts above I made up a quick conversation with ChatGPT about creating a simple REST API with NestJS, Mongo, and NATS. The example below is not something sophisticated but it clearly demonstrates the benefits of this capability:

  • you don’t need to write your request in full detail from the start
  • you can ask for variations (a moment when I ask him to redo using annotations)
  • you can go back on the work done and ask for an update based on the changed situation (a moment when I ask him to update the module file after adding NATS)

And during your entire journey, ChatGPT gives you detailed explanations of the code produced, enriching your knowledge.

As a bottom line before you continue to my sample conversation with ChatGPT: don’t take AI as a threat to your position or profession, but rather as an extension of your mind, a valuable companion, and a teacher in your journey to the new exciting goals. Don’t fear AI, embrace it and use it to your advantage.

PS: Some parts of this article were inspired, written, or improved by ChatGPT cause I code better than write texts or communicate with humans 🙂

Example

My replicas are marked as quotations. The rest of the text is ChatGPT output.

please generate a model in TypeScript for Post

Here is a basic model for a Post object in TypeScript:

class Post {
id: number;
title: string;
body: string;
constructor(id: number, title: string, body: string) {
this.id = id;
this.title = title;
this.body = body;
}
}

This model has three properties: idtitle, and body. The id property is a number, the title property is a string, and the body property is a string. The constructor function is used to create new instances of the Post class and set the initial values for the idtitle, and body properties.

You can use this model to create new Post objects like this:const myPost = new Post(1, ‘My Post Title’, ‘This is the body of my post.’);

I hope this helps! Let me know if you have any other questions.

Can you generate a Mongoose schema for it using NestJS

Sure, here is a Mongoose schema for a Post object that can be used with NestJS:import * as mongoose from ‘mongoose’;

export const PostSchema = new mongoose.Schema({
id: { type: Number, required: true },
title: { type: String, required: true },
body: { type: String, required: true },
});

This schema defines the structure of a Post object in a MongoDB database. It has three properties: idtitle, and body. The id property is a number and is required, the title property is a string and is required, and the body property is a string and is also required.

To use this schema in your NestJS application, you can import it into your code and pass it to the @nestjs/mongoose module’s forFeature function. This will register the schema with Mongoose and allow you to use it in your application. Here is an example:

import { Module } from '@nestjs/common';
import { MongooseModule } from '@nestjs/mongoose';
import { PostSchema } from './post.schema';
@Module({
imports: [
MongooseModule.forFeature([{ name: 'Post', schema: PostSchema }]),
],
})
export class PostModule {}

You can then use the Post schema in your application’s controllers and services to interact with the Post documents in your MongoDB database.

I hope this helps! Let me know if you have any other questions.

Can you make schema using annotations?

Yes, you can use TypeScript’s decorators to create a schema for a Post object that can be used with the Mongoose ODM. Here is an example:

import { Prop, Schema, SchemaFactory } from '@nestjs/mongoose';
import { Document } from 'mongoose';
@Schema()
export class Post extends Document {
@Prop({ required: true })
id: number;
@Prop({ required: true })
title: string;
@Prop({ required: true })
body: string;
}
export const PostSchema = SchemaFactory.createForClass(Post);

This code defines a Post class that extends the Document class from the mongoose module. It uses TypeScript decorators to define the schema for the Post class. The @Schema decorator is used to define the overall schema for the class, and the @Prop decorator is used to define the individual properties of the class.

The PostSchema constant is then created by calling the SchemaFactory.createForClass function and passing the Post class as an argument. This creates a Mongoose schema that can be used with the @nestjs/mongoose module.

To use this schema in your NestJS application, you can import it into your code and pass it to the @nestjs/mongoose module’s forFeature function, just like in the previous example.

I hope this helps! Let me know if you have any other questions.

Can you create controller for it using DTO

Yes, you can use a Data Transfer Object (DTO) to create a controller for a Post object in NestJS. Here is an example:

import { Controller, Get, Post, Body } from '@nestjs/common';
import { PostDto } from './post.dto';
@Controller('posts')
export class PostController {
@Post()
create(@Body() postDto: PostDto) {
// Insert code here to create a new Post
}
@Get()
findAll() {
// Insert code here to find all Post objects
}
}

This controller defines two methods: create and findAll. The create method is used to create a new Post object and is decorated with the @Post decorator. The @Body decorator is used to extract the PostDto object from the request body and pass it as an argument to the create method.

The findAll method is used to find all Post objects in the database and is decorated with the @Get decorator.

The PostDto class is defined in a separate post.dto.ts file and looks like this:

import { IsNumber, IsString } from 'class-validator';
export class PostDto {
@IsNumber()
id: number;
@IsString()
title: string;
@IsString()
body: string;
}

This class defines the structure of the data that is expected in a Post object. It uses TypeScript decorators from the class-validator module to define the data types and constraints for the properties of the Post class.

I hope this helps! Let me know if you have any other questions.

Can you generate service?

Yes, you can use a service to manage the data for a Post object in NestJS. Here is an example:

import { Injectable } from '@nestjs/common';
import { InjectModel } from '@nestjs/mongoose';
import { Model } from 'mongoose';
import { Post } from './post.schema';
import { PostDto } from './post.dto';
@Injectable()
export class PostService {
constructor(@InjectModel(Post.name) private readonly postModel: Model<Post>) {}
async create(postDto: PostDto): Promise<Post> {
const createdPost = new this.postModel(postDto);
return createdPost.save();
}
async findAll(): Promise<Post[]> {
return this.postModel.find().exec();
}
}

This service defines two methods: create and findAll. The create method is used to create a new Post object and save it to the database. It takes a PostDto object as an argument and uses the postModel property (which is injected using the @InjectModel decorator) to create a new Post object and save it to the database.

The findAll method is used to find all Post objects in the database. It uses the postModel property to query the database and returns an array of Post objects.

I hope this helps! Let me know if you have any other questions.

Can you update controller to use this service?

Yes, you can update the PostController to use the PostService to manage the data for Post objects. Here is an example:

import { Controller, Get, Post, Body } from '@nestjs/common';
import { PostDto } from './post.dto';
import { PostService } from './post.service';
@Controller('posts')
export class PostController {
constructor(private readonly postService: PostService) {}
@Post()
create(@Body() postDto: PostDto) {
return this.postService.create(postDto);
}
@Get()
findAll() {
return this.postService.findAll();
}
}

In this updated version of the PostController, the create and findAll methods are removed and the PostService is injected using the constructor. The create and findAll methods are then delegated to the PostService instance, and the controller simply returns the results of those methods.

This separates the business logic for managing Post objects into the PostService, making the controller’s code simpler and easier to understand. It also makes the PostController more testable, since you can easily mock the PostService when testing the controller.

I hope this helps! Let me know if you have any other questions.

Great! Could you also send a message to NATS once a post is created?

Yes, you can use the NATS messaging system to send a message when a new Post object is created. Here is an example of how you might update the PostService to do this:

import { Injectable } from '@nestjs/common';
import { InjectModel } from '@nestjs/mongoose';
import { Model } from 'mongoose';
import { Post } from './post.schema';
import { PostDto } from './post.dto';
import { Client, Message } from 'nats';
@Injectable()
export class PostService {
constructor(
@InjectModel(Post.name) private readonly postModel: Model<Post>,
private readonly natsClient: Client,
) {}
async create(postDto: PostDto): Promise<Post> {
const createdPost = new this.postModel(postDto);
const savedPost = await createdPost.save();
// Create a NATS message
const message = JSON.stringify({
id: savedPost.id,
title: savedPost.title,
body: savedPost.body,
});
// Publish the message to the 'posts' NATS subject
this.natsClient.publish('posts', message);
return savedPost;
}
async findAll(): Promise<Post[]> {
return this.postModel.find().exec();
}
}

This updated version of the PostService injects the NATS client using the constructor. Then, in the create method, after the Post object is saved to the database, a NATS message is created and published to the posts subject.

The NATS message contains the idtitle, and body of the Post object that was just created. Other services or applications that are subscribed to the posts subject will receive this message and can take action based on the contents of the message.

I hope this helps! Let me know if you have any other questions.

Could you update module file based on these changes?

Yes, you can update the module file to include the PostService and the NATS client. Here is an example of how the PostModule might be updated:

import { Module } from '@nestjs/common';
import { MongooseModule } from '@nestjs/mongoose';
import { ClientModule } from '@nestjs/microservices';
import { PostController } from './post.controller';
import { PostService } from './post.service';
import { PostSchema } from './post.schema';
@Module({
imports: [
MongooseModule.forFeature([{ name: 'Post', schema: PostSchema }]),
ClientModule.register({
options: {
url: 'nats://localhost:4222',
},
}),
],
controllers: [PostController],
providers: [PostService],
})
export class PostModule {}

This updated version of the PostModule imports the ClientModule from the @nestjs/microservices package and registers the NATS client with the module. It also adds the PostService to the list of providers for the module.

This allows the PostService to be injected into the PostController and the NATS client to be injected into the PostService.

I hope this helps! Let me know if you have any other questions.