
(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
- I have an error oauth with Microsoft
invalid_request: The provided value for the input parameter 'redirect_uri' is not valid. The expected value is a URI which matches a redirect URI registered for...
- Flutter Google Auth (Access blocked: Thi...
It is working fine on web platform, but on Flutter I'm getting this error. Any option to fix, or this issue with AppWrite and need to use different option? Ac...
- Reset Password , using createEmailToken ...
I am trying to reset password using OTP instead of recovery mail i success to create token (6 digit) from App write and verifying the OTP but in password reset,...
