(by the way, if you return return NextResponse.json(error)
instead, you only need to make if statements like if data.type ==
)
api does not require pages
oh? then i would have to read up how that works exactly. Thank you though and ill try to get this functional
api is kind of it's own thing, now called "route handlers" https://nextjs.org/docs/app/building-your-application/routing/route-handlers
(still needs to be in the /app folder though)
ooooh so since i have it in src/app/util/node-appwrite.js I should be able to call it using fetch(/util/node-appwrite)
?
api routes need to be in /app/api folder
gotcha thanks!
otherwise it will not work correctly
also, if you use any edge runtime (like cloudflare pages or vercel), they will automatically optimize these routes for you, as long as you use /api
ok. Well im selfhosted so i dont make use of either.
For proper structuring, read this part: https://nextjs.org/docs/app/building-your-application/routing/route-handlers#convention
will do. One last question. I currently have all my server functions in 1 file. Do i need to make new files for every function?
asking because i have 35 functions that would have to be converted.
You do not.
For example my folder structure for server actions is:
/src/app -- stuff here /src/utils/actions/category/specificName.ts
Category would be for example "user" or "account", where the file you can name whatever you want, but this is more of organizational purposes
Where my /src/utils/actions/user/account.ts file would look like this:
'use server'
import { createSessionServerClient } from '@/app/appwrite-session'
import { Models } from 'node-appwrite'
export async function changeEmail(email: string, password: string) {
try {
const { account } = await createSessionServerClient()
return await account.updateEmail(email, password)
} catch (error) {
return JSON.parse(JSON.stringify(error))
}
}
export async function changePassword(
newPassword: string,
currentPassword: string
) {
try {
const { account } = await createSessionServerClient()
return await account.updatePassword(newPassword, currentPassword)
} catch (error) {
return JSON.parse(JSON.stringify(error))
}
}
export async function changePreferences(body: Models.Preferences) {
try {
const { account } = await createSessionServerClient()
return await account.updatePrefs(body)
} catch (error) {
return JSON.parse(JSON.stringify(error))
}
}
export async function changeProfileUrl(profileUrl: string) {
try {
const { account, databases } = await createSessionServerClient()
const userMe = await account.get()
return await databases.updateDocument('hp_db', 'userdata', userMe?.$id, {
profileUrl: profileUrl,
})
} catch (error) {
return JSON.parse(JSON.stringify(error))
}
}
As you can see, it's only specific to the user part
This clears up some things, if you ever get an error in your file, your entire file will probably break
Alright I would have to read this over couple of times to make sense of it but I think i can apply this.
Thank you very much for your time and patience
Also, here is a good example of the appwrite.ts file:
import {
Client,
Account,
Teams,
Functions,
Databases,
Storage,
Messaging,
Locale,
Avatars,
} from 'node-appwrite'
import { headers } from 'next/headers'
export async function createSessionServerClient() {
const headersList = headers()
const cookieHeader = headersList.get('cookie')
const cookies = cookieHeader ? cookieHeader.split('; ') : []
const sessionCookie = cookies.find((cookie) => cookie.startsWith('a_session'))
const client = new Client()
.setEndpoint(`${process.env.NEXT_PUBLIC_API_URL}/v1`)
.setProject(process.env.NEXT_PUBLIC_APPWRITE_PROJECT_ID)
if (sessionCookie) {
client.setSession(sessionCookie.split('=')[1])
}
return {
get account() {
return new Account(client)
},
get teams() {
return new Teams(client)
},
get databases() {
return new Databases(client)
},
get storage() {
return new Storage(client)
},
get functions() {
return new Functions(client)
},
get messaging() {
return new Messaging(client)
},
get locale() {
return new Locale(client)
},
get avatars() {
return new Avatars(client)
},
}
}
export async function createSessionClient(request: any) {
const client = new Client()
.setEndpoint(`${process.env.NEXT_PUBLIC_API_URL}/v1`)
.setProject(process.env.NEXT_PUBLIC_APPWRITE_PROJECT_ID)
const session = request.cookies.get(
`a_session_${process.env.NEXT_PUBLIC_APPWRITE_PROJECT_ID}`
)
if (session) {
client.setSession(session.value)
}
return {
get account() {
return new Account(client)
},
get teams() {
return new Teams(client)
},
get databases() {
return new Databases(client)
},
get storage() {
return new Storage(client)
},
get functions() {
return new Functions(client)
},
get messaging() {
return new Messaging(client)
},
get locale() {
return new Locale(client)
},
get avatars() {
return new Avatars(client)
},
}
}
export async function createAdminClient() {
const client = new Client()
.setEndpoint(`${process.env.NEXT_PUBLIC_API_URL}/v1`)
.setProject(process.env.NEXT_PUBLIC_APPWRITE_PROJECT_ID)
.setKey(process.env.APPWRITE_API_KEY)
return {
get account() {
return new Account(client)
},
get teams() {
return new Teams(client)
},
get databases() {
return new Databases(client)
},
get storage() {
return new Storage(client)
},
get functions() {
return new Functions(client)
},
get messaging() {
return new Messaging(client)
},
get locale() {
return new Locale(client)
},
get avatars() {
return new Avatars(client)
},
}
}
createSessionServerClient
will be used the most in my case, for example on any page that is on the server, you can just do:
const { account } = await createSessionServerClient()
const userData = await account.get()
--
createSessionClient
is kind of for using api route handler requests, mostly not needed if you don't really use any api routes
and createAdminClient
for admin stuffs
I saw you are using const session = cookies().get(userCookie);
, which is displayed in the docs, but this is very incorrect, as cookies().get cannot read HTTPOnly cookies, lol.
-_- xD well thanks for letting me know.
HTTPOnly cookies can only be read from the headers, so it's 100% sure that the token only gets sent to the server and not to clients
i will adjust that.
Just do add to this, the code I sent here for the api route does create a httponly cookie, hence why I said it
If your issue has been solved, please add [SOLVED] to the beginning of the title. Happy Appwriting! :appwriterocket:
Recommended threads
- Send Email Verification With REST
I am using REST to create a user on the server side after receiving form data from the client. After the account is successfully created i wanted to send the v...
- Use different email hosts for different ...
Hello, I have 2 projects and i want to be able to set up email templates in the projects. Both projects will have different email host configurations. I see ...
- Deep Linking & Password reset
I am using react native with expo. I want to implement deep link with the url recived via email. So when clicked the link it opens my app. I havent ever used de...