Skip to content

Mongoose Orm Implemented in Encore Example #205

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 2 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions ts/mongoose-orm/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
node_modules
6 changes: 6 additions & 0 deletions ts/mongoose-orm/app/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
.encore
encore.gen.go
encore.gen.cue
/.encore
node_modules
/encore.gen
153 changes: 153 additions & 0 deletions ts/mongoose-orm/app/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,153 @@
# REST API Starter

This is a RESTful API Starter with a single Hello World API endpoint.

## Prerequisites

**Install Encore:**
- **macOS:** `brew install encoredev/tap/encore`
- **Linux:** `curl -L https://encore.dev/install.sh | bash`
- **Windows:** `iwr https://encore.dev/install.ps1 | iex`

## Create app

Create a local app from this template:

```bash
encore app create my-app-name --example=ts/hello-world
```

## Run app locally

Run this command from your application's root folder:

```bash
encore run
```
### Using the API

To see that your app is running, you can ping the API.

```bash
curl http://localhost:4000/hello/World
```

### Local Development Dashboard

While `encore run` is running, open [http://localhost:9400/](http://localhost:9400/) to access Encore's [local developer dashboard](https://encore.dev/docs/observability/dev-dash).

Here you can see traces for all requests that you made, see your architecture diagram (just a single service for this simple example), and view API documentation in the Service Catalog.

## Development

### Add a new service

To create a new microservice, add a file named encore.service.ts in a new directory.
The file should export a service definition by calling `new Service`, imported from `encore.dev/service`.

```ts
import { Service } from "encore.dev/service";

export default new Service("hello");
```

Encore will now consider this directory and all its subdirectories as part of the service.

Learn more in the docs: https://encore.dev/docs/ts/primitives/services

### Add a new endpoint

Create a new `.ts` file in your new service directory and write a regular async function within it. Then to turn it into an API endpoint, use the `api` function from the `encore.dev/api` module. This function designates it as an API endpoint.

Learn more in the docs: https://encore.dev/docs/ts/primitives/defining-apis

### Service-to-service API calls

Calling API endpoints between services looks like regular function calls with Encore.ts.
The only thing you need to do is import the service you want to call from `~encore/clients` and then call its API endpoints like functions.

In the example below, we import the service `hello` and call the `ping` endpoint using a function call to `hello.ping`:

```ts
import { api } from "encore.dev/api"; // import 'api' Service

export const post = api.raw(
{expose:true, method:"POST", path:"/"},
async (req, resp) => {
const body:
string
= await getBody(req);
try {

const response = await helloProvider.createNewEntity(JSON.parse(body))
resp.setHeader("Content-Type", "application/json");
resp.end(JSON.stringify(response ));
} catch (err) {
console.log(err)
const e = err as Error;
resp.statusCode = 500;
resp.end(e.message);
return;
}

},
)
```

Learn more in the docs: https://encore.dev/docs/ts/primitives/api-calls

Once you've added a migration, restart your app with `encore run` to start up the database and apply the migration. Keep in mind that you need to have [Docker](https://docker.com) installed and running to start the database.

Learn more in the docs: https://encore.dev/docs/ts/primitives/databases

### Learn more

There are many more features to explore in Encore.ts, for example:

- [Request Validation](https://encore.dev/docs/ts/primitives/validation)
- [Streaming APIs](https://encore.dev/docs/ts/primitives/streaming-apis)
- [Cron jobs](https://encore.dev/docs/ts/primitives/cron-jobs)
- [Pub/Sub](https://encore.dev/docs/ts/primitives/pubsub)
- [Object Storage](https://encore.dev/docs/ts/primitives/object-storage)
- [Secrets](https://encore.dev/docs/ts/primitives/secrets)
- [Authentication handlers](https://encore.dev/docs/ts/develop/auth)
- [Middleware](https://encore.dev/docs/ts/develop/middleware)

## Deployment

### Self-hosting

See the [self-hosting instructions](https://encore.dev/docs/self-host/docker-build) for how to use `encore build docker` to create a Docker image and configure it.

### Encore Cloud Platform

Deploy your application to a free staging environment in Encore's development cloud using `git push encore`:

```bash
git add -A .
git commit -m 'Commit message'
git push encore
```

You can also open your app in the [Cloud Dashboard](https://app.encore.dev) to integrate with GitHub, or connect your AWS/GCP account, enabling Encore to automatically handle cloud deployments for you.

## Link to GitHub

Follow these steps to link your app to GitHub:

1. Create a GitHub repo, commit and push the app.
2. Open your app in the [Cloud Dashboard](https://app.encore.dev).
3. Go to **Settings ➔ GitHub** and click on **Link app to GitHub** to link your app to GitHub and select the repo you just created.
4. To configure Encore to automatically trigger deploys when you push to a specific branch name, go to the **Overview** page for your intended environment. Click on **Settings** and then in the section **Branch Push** configure the **Branch name** and hit **Save**.
5. Commit and push a change to GitHub to trigger a deploy.

[Learn more in the docs](https://encore.dev/docs/how-to/github)


## Testing

To run tests, configure the `test` command in your `package.json` to the test runner of your choice, and then use the command `encore test` from the CLI. The `encore test` command sets up all the necessary infrastructure in test mode before handing over to the test runner. [Learn more](https://encore.dev/docs/ts/develop/testing)

```bash
encore test
```
6 changes: 6 additions & 0 deletions ts/mongoose-orm/app/encore.app
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{
// The app is not currently linked to the encore.dev platform.
// Use "encore app link" to link it.
"id": "",
"lang": "typescript",
}
24 changes: 24 additions & 0 deletions ts/mongoose-orm/app/hello/db.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import mongoose from "mongoose";
// import { UserModel } from "./entities/cat.entity";
import { Schema, Document } from "mongoose";



const MONGO_URI = process.env.MONGO_URI || "mongodb://localhost:27017/mydb";

export const connectDB = async () => {
try {
await mongoose.connect(MONGO_URI, {
dbName: "mydb",
});

// return UserModel

console.log("MongoDB connected successfully");
} catch (error) {
console.error("MongoDB connection error:", error);
process.exit(1);
}
};


7 changes: 7 additions & 0 deletions ts/mongoose-orm/app/hello/encore.service.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import { Service } from "encore.dev/service";

// Encore will consider this directory and all its subdirectories as part of the "hello" service.
// https://encore.dev/docs/ts/primitives/services

// hello service responds to requests with a personalized greeting.
export default new Service("hello");
20 changes: 20 additions & 0 deletions ts/mongoose-orm/app/hello/entities/cat.entity.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@

import mongoose, { Document } from "mongoose"
import { EntitiesName } from "./entities"

export interface ICat extends Document {
name:string
_id:mongoose.Schema.Types.ObjectId
}


const CatSchema = new mongoose.Schema<ICat>({
name:{
type:String
}
},{
timestamps:true,
collection:EntitiesName.cat.collectionName
})

export const CatModel = mongoose.model<ICat>(EntitiesName.cat.tableName,CatSchema )
13 changes: 13 additions & 0 deletions ts/mongoose-orm/app/hello/entities/entities.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
interface IEntityName {
[key: string]: {
collectionName: string;
tableName: string;
};
}

export const EntitiesName: IEntityName = {
cat: {
collectionName: "cat",
tableName: "cats",
},
};
9 changes: 9 additions & 0 deletions ts/mongoose-orm/app/hello/hello.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import { describe, expect, test } from "vitest";
import { get } from "./hello";

describe("get", () => {
test("should combine string with parameter value", async () => {
const resp = await get({ name: "world" });
expect(resp.message).toBe("Hello world!");
});
});
103 changes: 103 additions & 0 deletions ts/mongoose-orm/app/hello/hello.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
import { api } from "encore.dev/api";
import { IncomingMessage } from "http";
import { connectDB } from "./db";
import { helloProvider } from "./modules/hello.provider";


connectDB()


function getBody(req: IncomingMessage): Promise<any> {
return new Promise((resolve) => {
const bodyParts: any[] = [];
req
.on("data", (chunk) => {
bodyParts.push(chunk);
})
.on("end", () => {
resolve(Buffer.concat(bodyParts).toString());
});
});
}
// Welcome to Encore!
// This is a simple "Hello World" project to get you started.
//
// To run it, execute "encore run" in your favorite shell.

// ==================================================================

// This is a simple REST API that responds with a personalized greeting.
// To call it, run in your terminal:
// console.log(UserModel)
//
// curl http://localhost:4000/hello/World
//
export const get = api.raw(
{ expose: true, method: "GET", path: "/list" },
async (req, resp) => {
try {
console.log("hello I am update")
const response = await helloProvider.getEntityList()
resp.end( JSON.stringify(response))
} catch (error) {
console.log(error)
return {message:"hello"}
}
}
);

export const post = api.raw(
{expose:true, method:"POST", path:"/"},
async (req, resp) => {
const body:
string
= await getBody(req);
try {

const response = await helloProvider.createNewEntity(JSON.parse(body))
resp.setHeader("Content-Type", "application/json");
resp.end(JSON.stringify(response ));
} catch (err) {
console.log(err)
const e = err as Error;
resp.statusCode = 500;
resp.end(e.message);
return;
}

},
)

interface Response {
message: string;
}

// ==================================================================

// Encore comes with a built-in development dashboard for
// exploring your API, viewing documentation, debugging with
// distributed tracing, and more. Visit your API URL in the browser:
//
// http://localhost:9400
//

// ==================================================================

// Next steps
//
// 1. Deploy your application to the cloud
//
// git add -A .
// git commit -m 'Commit message'
// git push encore
//
// 2. To continue exploring Encore, check out these topics in docs:
//
// Building a REST API: https://encore.dev/docs/ts/tutorials/rest-api
// Creating Services: https://encore.dev/docs/ts/primitives/services
// Creating APIs: https://encore.dev/docs/ts/primitives/defining-apis
// Using SQL Databases: https://encore.dev/docs/ts/primitives/databases
// Using Pub/Sub: https://encore.dev/docs/ts/primitives/pubsub
// Authenticating users: https://encore.dev/docs/ts/develop/auth
// Using Cron Jobs: https://encore.dev/docs/ts/primitives/cron-jobs
// Using Secrets: https://encore.dev/docs/ts/primitives/secrets
42 changes: 42 additions & 0 deletions ts/mongoose-orm/app/hello/modules/hello.provider.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
import { CatModel, ICat } from "../entities/cat.entity";


class Hello {
private CatModel: typeof CatModel
constructor(){
this.CatModel = CatModel
}

/**
* @param payload {name: string}
* @returns Success Message with true and false with new Entry
*/
async createNewEntity(payload:{name:string}){
try {
const newEntity = await this.CatModel.create(payload)
return {Success:true, message:"Success", data:newEntity}
} catch (error) {
console.log(error)
}
}


/**
*
* @returns List of Data
*/
async getEntityList():Promise<{Success:boolean, message:string, data?:ICat[]}>{
try {
const entityList = await this.CatModel.find()
return {Success:true, message:"Success", data:entityList}

} catch (error) {
console.log(error)
return {Success:false, message:"Failed"}
}
}


}

export const helloProvider = new Hello()
Loading