Skip to content

Commit 5a392e3

Browse files
committed
feat: init rest-analog project
1 parent d8974fb commit 5a392e3

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

52 files changed

+1696
-0
lines changed

typescript/rest-analog/.editorconfig

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
# Editor configuration, see https://editorconfig.org
2+
root = true
3+
4+
[*]
5+
charset = utf-8
6+
indent_style = space
7+
indent_size = 2
8+
insert_final_newline = true
9+
trim_trailing_whitespace = true
10+
11+
[*.ts]
12+
quote_type = single
13+
14+
[*.md]
15+
max_line_length = off
16+
trim_trailing_whitespace = false

typescript/rest-analog/.gitignore

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
# See http://help.github.com/ignore-files/ for more about ignoring files.
2+
3+
# Compiled output
4+
/dist
5+
/tmp
6+
/out-tsc
7+
/bazel-out
8+
9+
# Node
10+
/node_modules
11+
npm-debug.log
12+
yarn-error.log
13+
14+
# IDEs and editors
15+
.idea/
16+
.project
17+
.classpath
18+
.c9/
19+
*.launch
20+
.settings/
21+
*.sublime-workspace
22+
23+
# Visual Studio Code
24+
.vscode/*
25+
!.vscode/settings.json
26+
!.vscode/tasks.json
27+
!.vscode/launch.json
28+
!.vscode/extensions.json
29+
.history/*
30+
31+
# Miscellaneous
32+
/.angular/cache
33+
/.nx/cache
34+
/.nx/workspace-data
35+
.sass-cache/
36+
/connect.lock
37+
/coverage
38+
/libpeerconnection.log
39+
testem.log
40+
/typings
41+
42+
# System files
43+
.DS_Store
44+
Thumbs.db

typescript/rest-analog/README.md

Lines changed: 291 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,291 @@
1+
# Fullstack Example with Analog (REST API)
2+
3+
This example shows how to implement a **fullstack app with [Analog](https://analogjs.org/)** using [Prisma Client](https://www.prisma.io/docs/reference/tools-and-interfaces/prisma-client). It uses a SQLite database file with some initial dummy data which you can find at [`./prisma/dev.db`](./prisma/dev.db).
4+
5+
## Getting started
6+
7+
### 1. Download example and install dependencies
8+
9+
Download this example:
10+
11+
```
12+
npx try-prisma@latest --template typescript/rest-analog
13+
```
14+
15+
Install npm dependencies:
16+
17+
```
18+
cd rest-analog
19+
npm install
20+
```
21+
22+
<details><summary><strong>Alternative:</strong> Clone the entire repo</summary>
23+
24+
Clone this repository:
25+
26+
```
27+
git clone [email protected]:prisma/prisma-examples.git --depth=1
28+
```
29+
30+
Install npm dependencies:
31+
32+
```
33+
cd prisma-examples/typescript/rest-analog
34+
npm install
35+
```
36+
37+
</details>
38+
39+
### 2. Create and seed the database
40+
41+
Run the following command to create your SQLite database file. This also creates the `User` and `Post` tables that are defined in [`prisma/schema.prisma`](./prisma/schema.prisma):
42+
43+
```
44+
npx prisma migrate dev --name init
45+
```
46+
47+
When `npx prisma migrate dev` is executed against a newly created database, seeding is also triggered. The seed file in [`prisma/seed.ts`](./prisma/seed.ts) will be executed and your database will be populated with the sample data.
48+
49+
### 3. Start the app
50+
51+
```
52+
npm run dev
53+
```
54+
55+
The app is now running, navigate to [`http://localhost:5173/`](http://localhost:5173/) in your browser to explore its UI.
56+
57+
<details><summary>Expand for a tour through the UI of the app</summary>
58+
59+
<br />
60+
61+
**Blog** (located in [`./src/app/pages/index.page.ts`](./src/app/pages/index.page.ts)
62+
63+
![](https://imgur.com/eepbOUO.png)
64+
65+
**Signup** (located in [`./rc/app/pages/signup.page.ts`](./src/app/pages/signup.page.ts))
66+
67+
![](https://imgur.com/iE6OaBI.png)
68+
69+
**Create post (draft)** (located in [`./src/app/pages/create.page.ts`](./src/app/pages/create.page.ts))
70+
71+
![](https://imgur.com/olCWRNv.png)
72+
73+
**Drafts** (located in [`./src/app/pages/drafts.page.ts`](./src/app/pages/drafts.page.ts))
74+
75+
![](https://imgur.com/PSMzhcd.png)
76+
77+
**View post** (located in [`./src/app/pages/p/_id.vue`](src/app/pages/post/_id.vue)) (delete or publish here)
78+
79+
![](https://imgur.com/zS1B11O.png)
80+
81+
</details>
82+
83+
## Using the REST API
84+
85+
You can also access the REST API of the API server directly. It is running on the same host machine and port and can be accessed via the `/api` route (in this case that is `localhost:3000/api/`, so you can e.g. reach the API with [`localhost:3000/api/feed`](http://localhost:3000/api/feed)).
86+
87+
### `GET`
88+
89+
- `/api/post/:id`: Fetch a single post by its `id`
90+
- `/api/feed`: Fetch all _published_ posts
91+
- `/api/filterPosts?searchString={searchString}`: Filter posts by `title` or `content`
92+
93+
### `POST`
94+
95+
- `/api/post`: Create a new post
96+
- Body:
97+
- `title: String` (required): The title of the post
98+
- `content: String` (optional): The content of the post
99+
- `authorEmail: String` (required): The email of the user that creates the post
100+
- `/api/user`: Create a new user
101+
- Body:
102+
- `email: String` (required): The email address of the user
103+
- `name: String` (optional): The name of the user
104+
105+
### `PUT`
106+
107+
- `/api/publish/:id`: Publish a post by its `id`
108+
109+
### `DELETE`
110+
111+
- `/api/post/:id`: Delete a post by its `id`
112+
113+
## Switch to another database (e.g. PostgreSQL, MySQL, SQL Server, MongoDB)
114+
115+
If you want to try this example with another database than SQLite, you can adjust the the database connection in [`prisma/schema.prisma`](./prisma/schema.prisma) by reconfiguring the `datasource` block.
116+
117+
Learn more about the different connection configurations in the [docs](https://www.prisma.io/docs/reference/database-reference/connection-urls).
118+
119+
<details><summary>Expand for an overview of example configurations with different databases</summary>
120+
121+
### PostgreSQL
122+
123+
For PostgreSQL, the connection URL has the following structure:
124+
125+
```prisma
126+
datasource db {
127+
provider = "postgresql"
128+
url = "postgresql://USER:PASSWORD@HOST:PORT/DATABASE?schema=SCHEMA"
129+
}
130+
```
131+
132+
Here is an example connection string with a local PostgreSQL database:
133+
134+
```prisma
135+
datasource db {
136+
provider = "postgresql"
137+
url = "postgresql://janedoe:mypassword@localhost:5432/notesapi?schema=public"
138+
}
139+
```
140+
141+
### MySQL
142+
143+
For MySQL, the connection URL has the following structure:
144+
145+
```prisma
146+
datasource db {
147+
provider = "mysql"
148+
url = "mysql://USER:PASSWORD@HOST:PORT/DATABASE"
149+
}
150+
```
151+
152+
Here is an example connection string with a local MySQL database:
153+
154+
```prisma
155+
datasource db {
156+
provider = "mysql"
157+
url = "mysql://janedoe:mypassword@localhost:3306/notesapi"
158+
}
159+
```
160+
161+
### Microsoft SQL Server
162+
163+
Here is an example connection string with a local Microsoft SQL Server database:
164+
165+
```prisma
166+
datasource db {
167+
provider = "sqlserver"
168+
url = "sqlserver://localhost:1433;initial catalog=sample;user=sa;password=mypassword;"
169+
}
170+
```
171+
172+
### MongoDB
173+
174+
Here is an example connection string with a local MongoDB database:
175+
176+
```prisma
177+
datasource db {
178+
provider = "mongodb"
179+
url = "mongodb://USERNAME:PASSWORD@HOST/DATABASE?authSource=admin&retryWrites=true&w=majority"
180+
}
181+
```
182+
183+
</details>
184+
185+
## Evolving the app
186+
187+
Evolving the application typically requires three steps:
188+
189+
1. Migrate your database using Prisma Migrate
190+
1. Update your server-side application code
191+
1. Build new UI features in Vue
192+
193+
For the following example scenario, assume you want to add a "profile" feature to the app where users can create a profile and write a short bio about themselves.
194+
195+
### 1. Migrate your database using Prisma Migrate
196+
197+
The first step is to add a new table, e.g. called `Profile`, to the database. You can do this by adding a new model to your [Prisma schema file](./prisma/schema.prisma) file and then running a migration afterwards:
198+
199+
```diff
200+
// schema.prisma
201+
202+
model Post {
203+
id Int @default(autoincrement()) @id
204+
title String
205+
content String?
206+
published Boolean @default(false)
207+
author User? @relation(fields: [authorId], references: [id])
208+
authorId Int
209+
}
210+
211+
model User {
212+
id Int @default(autoincrement()) @id
213+
name String?
214+
email String @unique
215+
posts Post[]
216+
+ profile Profile?
217+
}
218+
219+
+model Profile {
220+
+ id Int @default(autoincrement()) @id
221+
+ bio String?
222+
+ userId Int @unique
223+
+ user User @relation(fields: [userId], references: [id])
224+
+}
225+
```
226+
227+
Once you've updated your data model, you can execute the changes against your database with the following command:
228+
229+
```
230+
npx prisma migrate dev --name add-profile
231+
```
232+
233+
### 2. Update your application code
234+
235+
You can now use your `PrismaClient` instance to perform operations against the new `Profile` table. Here are some examples:
236+
237+
#### Create a new profile for an existing user
238+
239+
```ts
240+
const profile = await prisma.profile.create({
241+
data: {
242+
bio: 'Hello World',
243+
user: {
244+
connect: { email: '[email protected]' },
245+
},
246+
},
247+
})
248+
```
249+
250+
#### Create a new user with a new profile
251+
252+
```ts
253+
const user = await prisma.user.create({
254+
data: {
255+
256+
name: 'John',
257+
profile: {
258+
create: {
259+
bio: 'Hello World',
260+
},
261+
},
262+
},
263+
})
264+
```
265+
266+
#### Update the profile of an existing user
267+
268+
```ts
269+
const userWithUpdatedProfile = await prisma.user.update({
270+
where: { email: '[email protected]' },
271+
data: {
272+
profile: {
273+
update: {
274+
bio: 'Hello Friends',
275+
},
276+
},
277+
},
278+
})
279+
```
280+
281+
### 5. Build new UI features in Vue
282+
283+
Once you have added a new endpoint to the API (e.g. `/api/profile` with `/POST`, `/PUT` and `GET` operations), you can start building a new UI component in Vue. It could e.g. be called `profile.vue` and would be located in the `pages` directory.
284+
285+
In the application code, you can access the new endpoint via `fetch` operations and populate the UI with the data you receive from the API calls.
286+
287+
## Next steps
288+
289+
- Check out the [Prisma docs](https://www.prisma.io/docs)
290+
- Share your feedback on the [Prisma Discord](https://pris.ly/discord/)
291+
- Create issues and ask questions on [GitHub](https://github.com/prisma/prisma/)

0 commit comments

Comments
 (0)