Николай, привет!
>>> >> Пока искал решение задачи - понял её абсурдность: зачем делать запросы с условиями, если все данные на руках и можно фильровать их на месте.
1. Представь себе вытянуть многие сотни тысяч записей на клиент сразу.
2. Фильтрацию и сортировку сразу по нескольким полям (особенно при выборке сразу из нескольких таблиц) ты замахаешься делать на клиенте. Доволно простые для SQL задачи окажутся практически невозможными в реализации.
---
Это понятно, но для конкретного проекта - подходящее решение.
Вопрос:
Я сначала хотел запихать условие в
export async function getServerSideProps() {
const teches: Tech[] = await prisma.tech.findMany({
include: {
Category: true,
},
});
return {
props: {
initialTeches: teches,
},
};
}
Через свойство where. И как динамически это сделать на одной странице не разобрался. Была идея сделать пять страниц со своими параметрами. Хотел вынести в компонент и пропсами пробрасывать состояние выбранной категории. Но не свел все вместе с getServerSideProps().
Можешь подсказать, как было бы сделать правильно?
Дима, привет!
Вижу, что уже знаешь больше и можешь что-то сделать. Это хорошо. Но есть моменты, конечно.
>> Пока искал решение задачи - понял её абсурдность: зачем делать запросы с условиями, если все данные на руках и можно фильровать их на месте.
1. Представь себе вытянуть многие сотни тысяч записей на клиент сразу.
2. Фильтрацию и сортировку сразу по нескольким полям (особенно при выборке сразу из нескольких таблиц) ты замахаешься делать на клиенте. Доволно простые для SQL задачи окажутся практически невозможными в реализации.
>> Выяснилось, что единственное правилое для них место - папка public, дальше вложенность не имеет значения.
Все верно. По соображениям безопасности JS не отдает просто так любой файл как статику. Вдруг у тебя там когфиг с паролями? Поэтому в next-js настроена отдача статики из public. Но можно и свои кастомные папки сервить. К примеру, вот здесь у меня мидлвара ресайза картинок, а так же сервинг из папок shared/ и uploads/ https://github.com/prisma-cms/nextjs-nexus/blob/43e101b9804245bd551aefbf8e067cfd808c1d0d/server/index.ts#L26-L42
Где-то подсмотрел, как программист делает резюме на на тех технологиях, по которым ищет работу. Идея показалась интересной - решил повторить.
Собственно - вот: https://github.com/linklib/resume-v2
Озадачился вопросом поиска работы джуном по js. Для реализации резюме использую:
- React
- Typescript
- Next js
- Prisma
- SQLite
- Bootstrap React
Можно было бы обойтись без next и prisma, но тогда совсем бы "бедно" вышло. Хорошо бы было и Graphql использовать, но я с ним ещё только в первом приближении разобрался, маловато будет. Остальное тоже не на высшем уровне, но и я вроде на джуна претендую, не выше.
Описывать буду "крупными мазками", заостряя внимание на те моменты, которые вызвали заметные затыки в процессе. Если будут вопросы - пишите комменты. Итак, постановка задачи.
Нужна страничка с текстовым описанием и перечень навыков с фозможностью фильтра по категориям.
1. Разворачиваем next.js с typescript.
2. Устанавливаем и инициируем prisma. Для БД выбрал SQLite: позволяет стянуть проект и запустить его без размышлений о подключении к любой другой системе.
3. Пишем схему и деплоим её в БД.
4. Посев данных: готовим файл с данными. Вот здесь сыграла злую шутку моя невнимательность. Проблема с shadows database решалась просто директивой в package.json
//Не
"prisma": {
"seed": "ts-node prisma/seed.ts"
},
//A
"prisma": {
"seed": "ts-node --compiler-options {\"module\":\"CommonJS\"} prisma/seed.ts"
},
5. Получение данных. Призмой забираем данные из БД с использованием SSR Next js. Так как призма позволяет не только получить данные, но итфильтровать по нужному параметру, я ошибочно пошел по пути фильтрайии на этапе получения. Пока искал решение задачи - понял её абсурдность: зачем делать запросы с условиями, если все данные на руках и можно фильровать их на месте. В итоге получился фильтр на React Hook с фильтром на этапе вывода данных.
6. Оформляем, добавляем для сео NextSeo.
Про картинки: в бд пишется путь к картинке. Сначала разместил картинки в папке images в корне, но отобразаться они категорически не хотели. Выяснилось, что единственное правилое для них место - папка public, дальше вложенность не имеет значения.
Вопросы и предложения принимаются с благодарностью.
Всем привет!
Перевел еще два курса: Базовый CSS и Базовый JavaScript. Даже если вы их уже прошли, советую пройти еще раз. Я исправил много неточностей и дополнил комментариями.
Интересный момент заметил. В задаче задание звучит так: Измените функцию welcomeToBooleans так, чтобы она возвращала true вместо false.
Просмотрел все выполненные решения, все участники просто взяли и заменили false на true. Но задачу можно было решить и интересней:
function welcomeToBooleans() {
return !false; // Change this line
}
Здесь важно отметить, что логические легко и однозначно меняют свои значения на противоположное, используя оператор !, который меняет логическое значение на противоположное. Так же этот оператор можно использовать и для преобразования данных. К примеру
!!"1" === true; // Строка "1" преобразовывается в логическое true за счет двойного логического отрицания
!!"0" === false; // "0" == 0, 0 == false, !!0 === false
!"" === true; // "Пустая строка" == false
Просто у нас же программирование, а не просто переписывание одного текста на другой ;)
А он есть) и коммит с добавлением есть. Тогда добавлю ссыль. Единственное, как фиксировать разные моменты проекта надо понять
Дима, привет!
Рад, что ты что-то для себя новое освоил:) Но все же еще надо над знаниями поработать. И очень важно: поработать над терминами. Пока что ты многое называешь совсем не своими именами. Примеры.
>> Табличка простая, подвешенная в воздухе, без связей.
И надо эту новую табличку запихать в БД:
Нет, это еще не табличка. Пока что это только схема, описывающая структуру таблицы. Вот когда ты yarn prisma:push выполнишь, вот тогда призма возьмет эту схему, прочитает, сопоставит с текущей базой данных и сгенерирует запросы для обновления этой базы данных так, что бы она соответствовала схеме. Плюс к этому, призма сгенерирует все необходимые методы и типы, чтобы можно было работать с базой данных средствами JS. Все, больше никаких функций эта схема не выполняет и напрямую к БД никак не относится.
>> //Расширяем объект Query, добавляя новое свойство tech
Посмотри внимательно, у тебя там не только tech добавляется, но и techs
Ну а в целом, было бы сильно полезней, если бы ты сделал под эту статью сам клон проекта, все на нем выполнил, что в статье описываешь, и потом вылил бы измененный проект на гитхаб и сослался бы уже на измененный код, а не на исходный. И каждый желающий мог бы себе склонировать проект, запустить, перепроверить информацию. Да, так дольше, но так сильно эффективней. Я так делаю обычно.
Топик несколько расширяет обзорное видео про вариацию prisma-cms. В видео добавляется новое поле, что далеко не впрямую экстраполируется на добавление новой таблицы в проект. Инструкция нужна для того, чтобы любой, еще не знакомый с этой технологией, понял как делать. Итак.
Задача: добавить в проект новую таблицу поста Технологии в свежий клон @prisma-cms/nextjs-nexus.
и первичный запуск. Порядок такой:
- git clone https://github.com/Fi1osof/nextjs-nexus
- yarn
- yarn dev
- подключение к БД
- yarn prisma:deploy для первичного создания таблиц БД
Здесь надо уточнить про "подключение к БД". Призма работает с четырьмя базами: MySQL, Postgres, SQLite, MongoDB. Про последнюю ничего сказать не могу, но вот остальными ситуация следующая: кроме подключенной в docker mysql базы ничего задействовать лично у меня не получилось. То есть ни mysql на хостинге (у себя на ubutu я что-то накосячил с установкой mysql и marinaDB, теперь ещё и удалить не могу:) ), ни postgres на Heroku, ни файлы SQLite не прокатили, так как для использования миграций требуется разрешение на создание shadow database - читать тут https://www.prisma.io/docs/concepts/components/prisma-migrate/shadow-database Я не разобрался, как побороть.
Здесь детально про разворачивание проекта: https://freecode.academy/topics/zapusk-testovogo-proekta-lokalno
2. Добавляем в схему новую таблицу. Это сюда: https://github.com/Fi1osof/nextjs-nexus/blob/master/prisma/schema.prisma
model Tech {
id String @id @default(cuid())
title String
desc String?
link String?
image String?
}
Табличка простая, подвешенная в воздухе, без связей.
И надо эту новую табличку запихать в БД:
yarn prisma:db:push
3. Дальше надо типизировать в nexus
добавляем папку Tech и файл index.ts
//Tech/index.ts
import { objectType, extendType } from 'nexus'
//Описываем новый тип
export const Tech = objectType({
name: 'Tech',
description: 'Технология',
sourceType: {
module: '@prisma/client',
export: 'Tech',
},
definition(t) {
t.nonNull.string('id')
t.nonNull.string('title')
t.string('desc')
t.string('link')
t.string('image')
},
})
//Расширяем объект Query, добавляя новое свойство tech
export const TechExtendQuery = extendType({
type: 'Query',
definition(t) {
t.crud.teches({
description: 'Список технологий',
filtering: true,
ordering: true,
})
t.crud.tech({
description: 'Технология',
})
},
})
Не забываем добавить экспорт сюда: https://github.com/Fi1osof/nextjs-nexus/blob/master/server/nexus/types/index.ts
export * from './Tech'
Для того, чтобы реализовать изменения в схеме надо "сделать миграцию"(?):
yarn prisma:migrate:create
4. В процессе работы со схемой приходится постоянно обновлять БД, что приводит к обнулению данных, а это не удобно (каждый раз заново заводить). Для решения
этого вопроса в prisma есть посев данных, то есть автоматическое наполнение таблиц данными. В @prisma-cms/nextjs-nexus метод используется, можем его расширить.
Для этого изменим файл https://github.com/Fi1osof/nextjs-nexus/blob/master/prisma/seed.ts
import { Prisma, PrismaClient } from '@prisma/client'
import { createPassword } from '../server/nexus/types/User/resolvers'
// Подключаем сами данные, которые будем сеять
import { tech } from './data'
//
const prisma = new PrismaClient()
const userData: Prisma.UserCreateInput[] = []
async function main() {
// eslint-disable-next-line no-console
console.log(`Start seeding ...`)
const password = process.env.SUDO_PASSWORD
if (!password) {
throw new Error('SUDO_PASSWORD env is empty')
} else {
userData.push({
username: 'admin',
password: await createPassword(password),
sudo: true,
})
}
for (const u of userData) {
await prisma.user
.create({
data: u,
})
.then((user) => {
// eslint-disable-next-line no-console
console.log(`Created user with id: ${user.id}`)
})
.catch(console.error)
}
// Закидываем данные в БД, в таблицу tech
await prisma.tech.createMany({
data: tech,
})
//
// eslint-disable-next-line no-console
console.log(`Seeding finished.`)
}
main()
.catch((e) => {
console.error(e)
process.exit(1)
})
.finally(async () => {
await prisma.$disconnect()
})
Файл с данными:
// data.ts в папке prisma, где и seed.ts
export const tech = [
{
title: 'Next JS',
desc: 'Fullstack React framework',
link: 'https://nextjs.org/static/twitter-cards/home.jpg',
image:
'https://decodenatura.com/static/fb8aa1bb70c9925ce1ae22dc2711b343/nextjs-logo.png',
},
{
title: 'Prisma',
desc: 'Fullstack React framework',
link: 'https://nextjs.org/static/twitter-cards/home.jpg',
image:
'https://decodenatura.com/static/fb8aa1bb70c9925ce1ae22dc2711b343/nextjs-logo.png',
},
]
Команда на посев:
yarn prisma:seed
5. Последнее, что не хватает для работы с данными - добавить сами запросы.
добавляем файл с простым запросом вывода всех технологий Tech.graphql
query teches {
teches {
id
title
desc
link
image
}
}
Теперь нужно провести "генерацию типов"(?):
yarn generate:types
Теперь можно получать данные.
Вот проект на github с текущими изменениями: https://github.com/linklib/resume/tree/840d329b51ffd95f4563076cec45b59f97dc475e
Тоже верно. Ну значит аполло буду ковырять уже на призма-цмс))
Пойми: есть задачи по настройке системы, а есть задачи по программированию. Все эти настройки отнимают очень много времени, а выхлопа дают очень мало. Вместо того, чтобы заниматься этим, ты мог бы, к примеру, SQL поучить. Все пользы было бы больше. SQL действительно важен. А настройка этих компонентов отдельных: высокоуровневым специалистом ты вряд ли станешь (даже я не тяну в этом направлении на такой уровень). И получается, что денег ты с этого не заработаешь (никто не станет платить нормальные деньги за работу низкого качества). При этом ты потеряешь в навыках того, что действительно должен знать и за что должны платить.
Если ты хочешь понять как призма работает, разбирай уже существующую систему (бери ломай и следи за тем, где что поменялось), но не пытайся этого выстроить с нуля самостоятельно. Самая коварная штука в том, что не зная как это должно работать, ты не сможешь нормально выстроить с нуля, и получется так, что даже если ты что-то сможешь сделать, вероятнее всего это будет не оптимально и не правильно. И ты попадешь в ловушку своих же знаний: будешь думать что понял, а на самом деле все совсем не так.