Skip to content

Commit

Permalink
feat: add API (lol)
Browse files Browse the repository at this point in the history
  • Loading branch information
fabien-roy committed May 4, 2022
1 parent 144f6c8 commit f711ee5
Show file tree
Hide file tree
Showing 21 changed files with 3,195 additions and 111 deletions.
5 changes: 5 additions & 0 deletions .eslintrc.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,4 +24,9 @@ module.exports = {
},
},
},
rules: {
// TODO: Yeah, Nuxt3 is cool, but should we really do this?
'no-undef': 'off',
},
ignorePatterns: ['generated/*'],
};
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,5 @@ node_modules
.nitro
.cache
.output
.env
.env
generated
3 changes: 1 addition & 2 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
# Nuxt 3 Template

Simple [Nuxt 3](https://v3.nuxtjs.org/) Template that uses
[an open GraphQL API about planets](https://github.com/ZaneTurner/PlanetsAPI).
Simple [Nuxt 3](https://v3.nuxtjs.org/) and [Apollo](https://www.apollographql.com/) Template about cars

Made with love by [Fabien Roy](https://github.com/ExiledNarwal28).

Expand Down
6 changes: 5 additions & 1 deletion TODO.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,15 @@ Bugfix

- (#1) Repair pre-commit hook (this shit:
`Error [ERR_PACKAGE_PATH_NOT_EXPORTED]: Failed to load plugin 'vue' declared in '.eslintrc.js': Package subpath './lib/rules/array-bracket-spacing' is not defined by "exports" in /home/hackerman/Dev/nuxt3-template/node_modules/eslint/package.json`)
- Weirdly, we need to refresh /car/:id. That's problematic.

Features

- Add basic pages and components
- Link Planets API
- Add more queries
- Add mutations
- Add i18n translations (see: https://github.com/intlify/nuxt3)
- Add styles (style-component?)

Docs

Expand Down
8 changes: 2 additions & 6 deletions app.vue
Original file line number Diff line number Diff line change
@@ -1,11 +1,7 @@
<template>
<div>
<h1>
Nuxt 3 Template
</h1>
<sub>
A simple app about planets.
</sub>
<h1>Nuxt 3 Template</h1>
<sub> A simple app about cars. </sub>
<NuxtPage />
</div>
</template>
12 changes: 12 additions & 0 deletions codegen.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
documents: graphql/**/*.gql
generates:
generated/schema.d.ts:
plugins:
- typescript
generated/operations.ts:
config:
documentMode: documentNode
plugins:
- typescript
- typescript-operations
- typescript-vue-apollo
5 changes: 5 additions & 0 deletions docs/index.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# Docs for Nuxt 3 Template

Yo, this is the docs.

- [References](references.md)
7 changes: 7 additions & 0 deletions docs/references.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
# References

Some damn good code thingies I found over the course of this project.

## Examples

- [newbeea/nuxt3-apollo-starter](https://github.com/newbeea/nuxt3-apollo-starter)
8 changes: 8 additions & 0 deletions graphql/car.query.gql
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
query Car($carInput: CarInput!) {
car(carInput: $carInput) {
id
brand
model
year
}
}
18 changes: 16 additions & 2 deletions nuxt.config.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,18 @@
import { defineNuxtConfig } from 'nuxt';
import { defineNuxtConfig } from 'nuxt3';

// https://v3.nuxtjs.org/api/configuration/nuxt.config
export default defineNuxtConfig({});
export default defineNuxtConfig({
build: {
transpile: ['graphql'],
},
buildModules: ['@nuxt3/graphql-codegen-module', '@nuxt3/apollo-module'],
graphqlCodegen: {
// TODO: Move to env var
schema: ['http://localhost:3000/api/graphql'],
},
apollo: {
default: {
uri: process.env.URL ? `${process.env.URL}/api/graphql` : 'http://localhost:3000/api/graphql',
},
},
});
20 changes: 18 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,25 @@
"prepare": "husky install",
"prettier": "prettier .",
"prettier:write": "prettier . --write",
"preview": "nuxt preview"
"preview": "nuxt preview",
"start": "node .output/server/index.mjs"
},
"dependencies": {
"@apollo/client": "^3.5.6",
"@nuxt3/apollo-module": "^0.0.9",
"@nuxt3/graphql-codegen-module": "^0.0.7",
"@vue/composition-api": "^1.6.0",
"apollo-server-core": "^3.6.7",
"class-validator": "^0.13.2",
"graphql": "^15.3.0",
"reflect-metadata": "^0.1.13",
"type-graphql": "^1.1.1"
},
"devDependencies": {
"@graphql-codegen/cli": "^2.6.2",
"@graphql-codegen/typescript": "^2.4.8",
"@graphql-codegen/typescript-operations": "^2.3.5",
"@graphql-codegen/typescript-vue-apollo": "^3.2.9",
"@typescript-eslint/eslint-plugin": "^5.22.0",
"@typescript-eslint/parser": "^5.22.0",
"@vue/cli-plugin-eslint": "^5.0.4",
Expand All @@ -28,7 +44,7 @@
"eslint-plugin-vue": "^7.0.0-beta.4",
"husky": "^7.0.0",
"lint-staged": "^12.4.1",
"nuxt": "3.0.0-rc.2",
"nuxt3": "^3.0.0-rc.2",
"prettier": "^2.6.2",
"typescript": "^4.6.4"
},
Expand Down
45 changes: 45 additions & 0 deletions pages/car/[id].vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
<script setup lang="ts">
// TODO: Why do I need to define this?
import { useCarQuery } from '~/generated/operations';
const route = useRoute();
const { result, loading, error } = useCarQuery({ carInput: { id: route.params.id } });
const car = result?.value?.car;
/*
definePageMeta({
title: car ? `Car with id ${car.id}` : '...',
});
*/
</script>

<template>
<div v-if="loading">
<span> Loading... </span>
</div>
<div v-else-if="error">
<span> Error: {{ error }} </span>
</div>
<div v-else-if="car">
<h2>Car with id {{ car.id }}</h2>
<div>
<strong> Brand: </strong>
<span>
{{ car.brand }}
</span>
</div>
<div>
<strong> Model: </strong>
<span>
{{ car.model }}
</span>
</div>
<div>
<strong> Year: </strong>
<span>
{{ car.year }}
</span>
</div>
</div>
</template>
16 changes: 11 additions & 5 deletions pages/index.vue
Original file line number Diff line number Diff line change
@@ -1,11 +1,17 @@
<script setup>
definePageMeta({
title: 'Yao, welcome m8'
})
title: 'Yao, welcome m8',
});
</script>

<template>
<h2>
Yao, welcome m8
</h2>
<div>
<h2>Yao, welcome m8</h2>
<div>
<NuxtLink to="/car/1"> Go to car with id '1' </NuxtLink>
</div>
<div>
<NuxtLink to="/car/2"> Go to car with id '2' </NuxtLink>
</div>
</div>
</template>
23 changes: 23 additions & 0 deletions server/api/graphql.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import * as Reflect from 'reflect-metadata';
import { buildSchemaSync } from 'type-graphql';
import resolvers from '../graphql';
import ApolloServer from '../graphql/apollo-server';

let schema;

if (Reflect) {
schema = buildSchemaSync({
resolvers,
});
} else {
throw new Error('No reflect-metadata polyfill');
}

const apolloServer = new ApolloServer({
schema,
});

apolloServer.start();
const handler = apolloServer.createHandler();

export default handler;
7 changes: 7 additions & 0 deletions server/api/pageview.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
const startAt = Date.now();
let count = 0;

export default () => ({
pageview: count++,
startAt,
});
41 changes: 41 additions & 0 deletions server/graphql/apollo-server.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
import type { IncomingMessage, ServerResponse } from 'http';
import { useBody, useQuery } from 'h3';
import type { GraphQLOptions } from 'apollo-server-core';
import { ApolloServerBase, convertNodeHttpToRequest, runHttpQuery } from 'apollo-server-core';

// TODO: Turn this into makeApolloServer()
export class ApolloServer extends ApolloServerBase {
async createGraphQLServerOptions(request?: IncomingMessage, reply?: ServerResponse): Promise<GraphQLOptions> {
return this.graphQLServerOptions({ request, reply });
}

createHandler() {
return async function (req: IncomingMessage, res: ServerResponse) {
const options = await this.createGraphQLServerOptions(req, res);
try {
const { graphqlResponse, responseInit } = await runHttpQuery([], {
method: req.method || 'GET',
options,
query: req.method === 'POST' ? await useBody(req) : await useQuery(req),
request: convertNodeHttpToRequest(req),
});
if (responseInit.headers) {
for (const [name, value] of Object.entries<string>(responseInit.headers)) {
res.setHeader(name, value);
}
}
res.end(graphqlResponse);
} catch (error) {
if (error.headers) {
for (const [name, value] of Object.entries<string>(error.headers)) {
res.setHeader(name, value);
}
}
res.statusCode = error.statusCode;
res.end(error.message);
}
}.bind(this);
}
}

export default ApolloServer;
26 changes: 26 additions & 0 deletions server/graphql/cars/car.resolver.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import { Resolver, Query, Arg } from 'type-graphql';
import { Car, CarInput } from './schema';

// TODO: Move mock data
const carData = [
{
id: '1',
brand: 'Toyota',
model: 'Camri',
year: 2006,
},
{
id: '2',
brand: 'Fort',
model: 'F-150',
year: 2012,
},
];

@Resolver()
export default class CarResolver {
@Query(() => Car)
car(@Arg('carInput', () => CarInput) carInput: CarInput) {
return carData.find(car => car.id === carInput.id);
}
}
22 changes: 22 additions & 0 deletions server/graphql/cars/schema.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import { Field, InputType, ObjectType } from 'type-graphql';

@InputType()
export class CarInput {
@Field(() => String)
id: string;
}

@ObjectType()
export class Car {
@Field(() => String)
id: string;

@Field(() => String)
brand: string;

@Field(() => String)
model: string;

@Field(() => Number)
year: number;
}
7 changes: 7 additions & 0 deletions server/graphql/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import type { NonEmptyArray } from 'type-graphql';
import car from './cars/car.resolver';

// eslint-disable-next-line @typescript-eslint/ban-types
const resolvers: NonEmptyArray<Function> = [car];

export default resolvers;
5 changes: 4 additions & 1 deletion tsconfig.json
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
{
"extends": "./.nuxt/tsconfig.json"
"extends": "./.nuxt/tsconfig.json",
"compilerOptions": {
"experimentalDecorators": true
}
}
Loading

0 comments on commit f711ee5

Please sign in to comment.