Skip to content

Commit

Permalink
vulcan artemis => vulcan fire
Browse files Browse the repository at this point in the history
  • Loading branch information
eric-burel committed May 11, 2022
1 parent 988117b commit 4eea1b8
Show file tree
Hide file tree
Showing 11 changed files with 73 additions and 74 deletions.
4 changes: 0 additions & 4 deletions docusaurus/docs/vulcan-artemis/_category_.json

This file was deleted.

13 changes: 0 additions & 13 deletions docusaurus/docs/vulcan-artemis/index.md

This file was deleted.

5 changes: 2 additions & 3 deletions docusaurus/docs/vulcan-express/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,20 +5,19 @@ title: "Vulcan Express"
# About Vulcan Express

[Vulcan Next](https://vulcan-next.vercel.app/) is our main stater for Vulcan.
However, you may want to reuse the magic of Vulcan outside of Next.js.
However, you may want to reuse the magic of Vulcan outside of Next.js.

For instance,
Next.js API routes, due to their serverless nature, cannot handle long-running tasks
such as cron-jobs.

Instead, you might want to create an Express based micro-server.


You could also want to use Vulcan with other frontend technologies, like Create React App, in which
case you need an additional Express server for the backend.

**Great news: we got you covered.**

[Vulcan Express](https://github.com/VulcanJS/vulcan-express) is the perfect solution for you!

Vulcan Express is in alpha stage, yet it works fine, uses TypeScript, Apollo Server, [Vulcan Artemis](../vulcan-artemis) for the CRUD operation, and is built using [Tsup](https://github.com/egoist/tsup) for a fast refresh during development.
Vulcan Express is in alpha stage, yet it works fine, uses TypeScript, Apollo Server, [Vulcan Fire](../vulcan-fire) for the CRUD operation, and is built using [Tsup](https://github.com/egoist/tsup) for a fast refresh during development.
4 changes: 4 additions & 0 deletions docusaurus/docs/vulcan-fire/_category_.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
{
"label": "Fire GraphQL",
"position": 2
}
Original file line number Diff line number Diff line change
@@ -1,44 +1,44 @@
---
title: "Custom resolvers"
---

# Why a custom resolver?

A custom resolver is needed for everything that is not a normal CRUD operation.

For example, creating an Article on a blog is a normal CRUD operation, and Vulcan Artemis handles that very well.
For example, creating an Article on a blog is a normal CRUD operation, and Vulcan Fire handles that very well.

However, triggering a spell-check algorithm server side is not a normal CRUD operation. For that you'll want a custom resolver.

## Top-level field resolvers

### Method 1. - Just write your resolver

You can still write an Apollo resolver as usual, as long as the name doesn't clash with an existing resolver generated by Artemis (avoid `createBlogArticle` for instance).

Forget everything about Artemis, you have zero obligation to use any of the helpers we provide.
You can still write an Apollo resolver as usual, as long as the name doesn't clash with an existing resolver generated by Fire (avoid `createBlogArticle` for instance).

Forget everything about Fire, you have zero obligation to use any of the helpers we provide.

### Method 2. - Use Artemis mutators to manipulate data
### Method 2. - Use Fire mutators to manipulate data

When writing a custom resolver, you will quickly understand why Vulcan Artemis is *so cool*. This is especially true if you need to do a CRUD operation inside your custom resolver. For instance if your resolver must update or create some data from the database.
When writing a custom resolver, you will quickly understand why Vulcan Fire is _so cool_. This is especially true if you need to do a CRUD operation inside your custom resolver. For instance if your resolver must update or create some data from the database.

You may need:

- to check if the user is authorized to do the operation
- to run some callbacks to update related data
- to send a database request

Hopefully, Artemis exposes it's internal logic via the concept of "Mutators".
Hopefully, Fire exposes it's internal logic via the concept of "Mutators".

A mutator is a function that includes all the heavy logic of Artemis. Our GraphQL resolvers
A mutator is a function that includes all the heavy logic of Fire. Our GraphQL resolvers
are actually just wrappers around mutator calls.

### /!\ Do not use Vulcan connectors directly to communicate with the database

Connectors are simplified function that fits exactly the need of Artemis CRUD operations. They allow us to support any database.
Connectors are simplified function that fits exactly the need of Fire CRUD operations. They allow us to support any database.

But they might feel limited if you use them directly. First because they can't support as many functionnalities as a normal database connector. Then because they won't run all the nice logic of Fire (no permission checks, no callbacks etc.)

But they might feel limited if you use them directly. First because they can't support as many functionnalities as a normal database connector. Then because they won't run all the nice logic of Artemis (no permission checks, no callbacks etc.)

Instead, either use a `mutator`, or call your database as you would do usually (using `mongo` or `mongoose`, a raw SQL query, etc.).

## Custom field resolvers
Expand All @@ -63,8 +63,8 @@ Field resolvers behave almost the same as top-level resolvers. So you can either

The only difference is that, if possible, you should use [DataSources](https://www.apollographql.com/docs/apollo-server/data/data-sources/). DataSources will reduce the number of calls to your database in many scenarios.

As a default, Artemis will generate [Mongo DataSources](https://github.com/GraphQLGuide/apollo-datasource-mongodb) for each model.
As a default, Fire will generate [Mongo DataSources](https://github.com/GraphQLGuide/apollo-datasource-mongodb) for each model.

**Be careful with ObjectId from Mongo ddocuments!** You should convert them to string ids before responding to a GraphQL request, otherwise you may end up with unexpected issues. Vulcan Artemis default relation resolvers and Mongoose connector will handle the conversion for you.
**Be careful with ObjectId from Mongo ddocuments!** You should convert them to string ids before responding to a GraphQL request, otherwise you may end up with unexpected issues. Vulcan Fire default relation resolvers and Mongoose connector will handle the conversion for you.

In your custom resolvers, you might need to use our `convertIdAndTransformToJSON` helper exported from `@vulcanjs/crud/server`, it works for a single document or an array of documents.
Original file line number Diff line number Diff line change
Expand Up @@ -3,29 +3,29 @@ title: "Get started"
sidebar_position: 2
---

**Vulcan Artemis is already included in [Vulcan Next](../vulcan-next) and is production-ready.**
**Vulcan Fire is already included in [Vulcan Next](../vulcan-next) and is production-ready.**

**Documentation in progress.**

# Easy CRUD for GraphQL servers

## In a nutshell

In greek mythology, Artemis is Apollo's twin sister.
That's why *Vulcan Artemis* completes *Apollo GraphQL* so well!
In greek mythology, Fire is Apollo's twin sister.
That's why _Vulcan Fire_ completes _Apollo GraphQL_ so well!

[Apollo GraphQL](https://www.apollographql.com/) provides a way to easily setup GraphQL in JavaScript applications, server-side and client-side.

**Vulcan Artemis** is a toolkit to be more productive with Apollo.
**Vulcan Fire** is a toolkit to be more productive with Apollo.

## Vulcan Artemis makes CRUD operations easy
## Vulcan Fire makes CRUD operations easy

When coding your application, you might notice that some operations are always the same for any kind of data:

- you need to Create, Update or Delete data
- you need to Read data, either a single document, or a list of items

This is what we call "CRUD" operations.
This is what we call "CRUD" operations.

In your Apollo server setup, this means that you need
to code at least 4 resolvers for each kind of data. A blog with Authors, Articles and Comments already needs 12 resolvers!
Expand All @@ -38,7 +38,7 @@ Yet, all your code will look vaguely the same: you check permissions, you update

## Free CRUD resolvers for your data model

**Vulcan Artemis provides:**
**Vulcan Fire provides:**

- 📡 Server-side, an engine to automatically generate your GraphQL schema based on a simple JavaScript object that describes your data
- 📡 Server-side, 5 default resolvers that can either mutate data (create, update, delete) or fetch data from your database (getting a single specific item, or a list of multiple items)
Expand All @@ -48,18 +48,18 @@ Yet, all your code will look vaguely the same: you check permissions, you update

## It works for any database

Artemis can plug to any database, as long as you can implement the basic CRUD operations to build what we call a "Connector".
Fire can plug to any database, as long as you can implement the basic CRUD operations to build what we call a "Connector".

We provide a Mongoose connector out-of-the-box.

## There is no lock-in

Vulcan Artemis makes you productive in the early stages of your application development, or even later on.
Vulcan Fire makes you productive in the early stages of your application development, or even later on.

However, if you start needing very custom and complexe code, there is absolutely no-restriction. You can still write normal Apollo GraphQL resolvers as you would do without Artemis.
However, if you start needing very custom and complexe code, there is absolutely no-restriction. You can still write normal Apollo GraphQL resolvers as you would do without Fire.

There is also no obligation to use Artemis hooks client-side. Or to use React. Or even to client-side GraphQL, thanks to tools such as [Wundergraph](https://wundergraph.com/). If you need only a backend, you might like our [Vulcan Express starter](../vulcan-express/).
There is also no obligation to use Fire hooks client-side. Or to use React. Or even to client-side GraphQL, thanks to tools such as [Wundergraph](https://wundergraph.com/). If you need only a backend, you might like our [Vulcan Express starter](../vulcan-express/).

## Give it a try!

The easiest way to start with Artemis, is to discover either our [Next.js starter](../vulcan-next) or our [Express starter](../vulcan-express).
The easiest way to start with Fire, is to discover either our [Next.js starter](../vulcan-next) or our [Express starter](../vulcan-express).
13 changes: 13 additions & 0 deletions docusaurus/docs/vulcan-fire/index.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
# Vulcan Fire

## In a nutshell

In Roman mythology, Vulcan is Apollo's Brother and god of fire.
That's why _Vulcan Fire_ completes _Apollo GraphQL_ so well!

[Apollo GraphQL](https://www.apollographql.com/) provides a way to easily setup GraphQL in JavaScript applications, server-side and client-side.

**Vulcan Fire** is a toolkit to be more productive with Apollo.
Fire powers our staters, [Vulcan Next](../vulcan-next) and [Vulcan Express](../vulcan-express/).

Go go to the next page to learn more.
Original file line number Diff line number Diff line change
@@ -1,21 +1,22 @@
---
title: Outside GraphQL
---
# Reuse Artemis logic in an Express endpoint

Artemis core logic doesn't really depend on GraphQL.
# Reuse Fire logic in an Express endpoint

Fire core logic doesn't really depend on GraphQL.

`mutator` functions are actually reusable in any Express application in a few easy steps.
They are exposed by the `@vulcanjs/crud/server` package.

In an Express middleware:

- Call `createMutator`, `updateMutator` or `deleteMutator` (check API docs for their full).
You'll need to pass the `currentUser`. If there is no current user, for instance if you use a mutator
in a seed script, instead use the `asAdmin` option and the `validate` option.
You'll need to pass the `currentUser`. If there is no current user, for instance if you use a mutator
in a seed script, instead use the `asAdmin` option and the `validate` option.

You can optionnaly pass the GraphQL context to a mutator, though it should not be needed anymore:

- Optionnaly generate the `context`. This is the same context that is used in GraphQL resolvers. This concept is less common outside of the GraphQL ecosystem, but still perfectly relevant.
- Generate `dataSources` as well
- Then you can use a `mutator` as you would do when creating a custom resolver, and pass it the `context` and `dataSources`.
- Then you can use a `mutator` as you would do when creating a custom resolver, and pass it the `context` and `dataSources`.
30 changes: 14 additions & 16 deletions docusaurus/docs/vulcan-next/comparison.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ The combination of middlewares and the data fetching methods provided by Next al

Also, Next.js includes API routes, which makes it a full-stack framework. API routes are limited to a serverless approach. The only issue is when you need long running tasks such as cron jobs. In this scenario, you can always couple Next with a tiny satellite Express server. We are currently (03/2022) working on a Vulcan Express starter as well.

## Vulcan vs other Next.js frameworks
## Vulcan vs other Next.js frameworks

### Blitz.js

Expand All @@ -32,46 +32,44 @@ Bison also relies on static code generation while we prefer a dynamic approach.

#### Boilerplate vs framework

Bison is a boilerplate, it's basically a extremely well-written Next.js app.
Bison is a boilerplate, it's basically a extremely well-written Next.js app.
Vulcan is a framework. It means that we provide a Next.js app too (I hope a well-written one :)), but also that a huge part of our code is actually usable outside of Next. Vulcan can work in any Express application for the backend or React application for the frontend.

We have a long history of being stuck with Meteor before moving to Next.js, that's why we try to make most of our codebase framework-independant.

### Next Right Now and other boilerplates

There are plenty of Next.js boilerplates that use various technologies. I won't quote all of them, but [Next Right Now](https://github.com/UnlyEd/next-right-now) is definitely worth a try. It's one of the earliest and most mature Next.js boilerplate around.

## Vulcan vs other non Next.js technologies

- [Create React App](https://create-react-app.dev/): to achieve the same level of features than with Next.js, CRA should be coupled with a server and bundler like [Vite](https://vitejs.dev/). This makes it a lower-level tool, while we like the turnkey approach of Next.js.

- [RedwoodJS](https://redwoodjs.com/): An excellent full-stack framework!
The only issue I could find is that prerendering is still limited to public content.
This limitation is also shared by other technologies at the time of writing (early 2022): SvelteKit, Gatsby.js...
- [RedwoodJS](https://redwoodjs.com/): An excellent full-stack framework!
The only issue I could find is that prerendering is still limited to public content.
This limitation is also shared by other technologies at the time of writing (early 2022): SvelteKit, Gatsby.js...

Next/Vulcan Next are able to handle multi-tenancy, i18n, A/B testing... more elegantly when it comes to static rendering.

In terms of philosophy, Vulcan is a cross-point between various technologies maintained by many different people: Next, Express, React, Storybook, Jest, Apollo, GraphQL... We don't really aim to invent a lot of "new things", but instead we gather the best ideas around the world and mix them in a single project.

- [Meteor](https://www.meteor.com/developers/): Meteor is one of the first mature fullstack JavaScript framework ever.
The first version of Vulcan was based on Meteor. Meteor and Vulcan brought many innovations: structuring the code as a monorepo of reusable packages, making it easy to share code between the client and the server, having a schema-based client/server communication layer...
- [Meteor](https://www.meteor.com/developers/): Meteor is one of the first mature fullstack JavaScript framework ever.
The first version of Vulcan was based on Meteor. Meteor and Vulcan brought many innovations: structuring the code as a monorepo of reusable packages, making it easy to share code between the client and the server, having a schema-based client/server communication layer...

However, Meteor development underwent a hiatus between 2016-2019 as the focus shifted on coding Apollo.
It was later bought by Tiny and now regains a new wave of attention, however we already moved out by that time. Meteor is still an excellent framework for medium-sized apps.

## Why no static code generation?

Using Vulcan, you might notice that we *dynamically* generate the GraphQL "Type Definitions" (the GraphQL schema as a) and "resolvers" (the function that powers this schema).

Many modern frameworks prefer *static* generation for both, meaning they will litterally produce pieces of code you can edit later on.
Using Vulcan, you might notice that we _dynamically_ generate the GraphQL "Type Definitions" (the GraphQL schema as a) and "resolvers" (the function that powers this schema).

Many modern frameworks prefer _static_ generation for both, meaning they will litterally produce pieces of code you can edit later on.

- Static code generation is awesome when you need to customize the code later on. However,
it also mean that you need to manage a lot of additional files in your codebase.
it also mean that you need to manage a lot of additional files in your codebase.

- Dynamic generation won't generate any code. Customization is done either via the Vulcan Model object, or by [creating your custom resolvers as depicted in our GraphQL engine documentation](../vulcan-fire/customResolvers.md).

- Dynamic generation won't generate any code. Customization is done either via the Vulcan Model object, or by [creating your custom resolvers as depicted in our GraphQL engine documentation](../vulcan-artemis/customResolvers.md).

Actually, both patterns are perfectly compatible!
Actually, both patterns are perfectly compatible!

For instance, you can use the generic, dynamic `useMulti` React hook from Vulcan to fetch data, but also generate some specific, static hooks using tools like [Wundergraph](https://wundergraph.com/).

Expand Down
10 changes: 5 additions & 5 deletions docusaurus/sidebars.js
Original file line number Diff line number Diff line change
Expand Up @@ -58,12 +58,12 @@ const sidebars = {
},
{
type: "category",
label: "Artemis GraphQL",
link: { type: "doc", id: "vulcan-artemis/index" },
label: "Fire GraphQL",
link: { type: "doc", id: "vulcan-fire/index" },
items: [
"vulcan-artemis/get-started",
"vulcan-artemis/customResolvers",
"vulcan-artemis/outsideGraphql",
"vulcan-fire/get-started",
"vulcan-fire/customResolvers",
"vulcan-fire/outsideGraphql",
],
},
{
Expand Down
7 changes: 4 additions & 3 deletions starters/remix/README.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# Vulcan Eurodance Stack

The Remix Eurodance Stack 🇪🇺 🐸 🛵
*Based on Remix [Indie Stack](https://github.com/remix-run/indie-stack)*
_Based on Remix [Indie Stack](https://github.com/remix-run/indie-stack)_

<!--![The Remix Eurodance Stack](https://repository-images.githubusercontent.com/465928257/a241fa49-bd4d-485a-a2a5-5cb8e4ee0abf)-->

Expand All @@ -25,7 +25,7 @@ npx create-remix --template VulcanJS/eurodance-stack

- Invisible GraphQL: work transparently with GraphQL, without ever depending client-side
- A GraphQL resource route with [GraphQL Yoga](https://www.graphql-yoga.com/)
- Vulcan Artemis Engine
- Vulcan Fire Engine

**MongoDB supports (via Prisma)**

Expand All @@ -38,6 +38,7 @@ Remix stacks hosts on Fly out-of-the-box.
For historical reasons Vulcan prefers Vercel, but you can deploy your Remix app almost anywhere very easily.

### From Remix indie stack:

- [Fly app deployment](https://fly.io) with [Docker](https://www.docker.com/)
- Production-ready [SQLite Database](https://sqlite.org)
- Healthcheck endpoint for [Fly backups region fallbacks](https://fly.io/docs/reference/configuration/#services-http_checks)
Expand Down Expand Up @@ -237,4 +238,4 @@ They give time and share knowledge to support the project.

## Other cool stuff that inspires us

- [remix-graphql](https://github.com/thomasheyenbrock/remix-graphql) served as a basis to setup GraphQL in Remix
- [remix-graphql](https://github.com/thomasheyenbrock/remix-graphql) served as a basis to setup GraphQL in Remix

0 comments on commit 4eea1b8

Please sign in to comment.