Skip to content

Commit

Permalink
added album and photo data to user object
Browse files Browse the repository at this point in the history
  • Loading branch information
enochval committed Jun 4, 2024
1 parent 4708aca commit fd378e1
Show file tree
Hide file tree
Showing 13 changed files with 192 additions and 26 deletions.
12 changes: 12 additions & 0 deletions src/albums/albums.module.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import { Module } from '@nestjs/common';
import { AlbumsService } from './albums.service';
import { HttpModule } from '@nestjs/axios';
import { PhotosService } from './photos/photos.service';
import { AlbumResolver } from './albums.resolver';

@Module({
imports: [HttpModule],
providers: [AlbumsService, AlbumResolver, PhotosService],
exports: [AlbumsService, PhotosService]
})
export class AlbumsModule {}
16 changes: 16 additions & 0 deletions src/albums/albums.resolver.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import { Parent, ResolveField, Resolver } from "@nestjs/graphql";
import { PhotosService } from "./photos/photos.service";
import { Photo } from "src/graphql";

@Resolver('Album')
export class AlbumResolver {

constructor(private readonly photosService: PhotosService) {}

@ResolveField('photos')
async getAlbumPhotos(@Parent() album): Promise<Photo[]> {
const { id } = album
return await this.photosService.getPhotosByAlbumId(id)
}

}
18 changes: 18 additions & 0 deletions src/albums/albums.service.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import { Test, TestingModule } from '@nestjs/testing';
import { AlbumsService } from './albums.service';

describe('AlbumsService', () => {
let service: AlbumsService;

beforeEach(async () => {
const module: TestingModule = await Test.createTestingModule({
providers: [AlbumsService],
}).compile();

service = module.get<AlbumsService>(AlbumsService);
});

it('should be defined', () => {
expect(service).toBeDefined();
});
});
31 changes: 31 additions & 0 deletions src/albums/albums.service.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import { HttpService } from '@nestjs/axios';
import { BadRequestException, Injectable, Logger } from '@nestjs/common';
import { ConfigService } from '@nestjs/config';
import { AxiosError } from 'axios';
import { catchError, firstValueFrom } from 'rxjs';
import { Album } from 'src/graphql';

@Injectable()
export class AlbumsService {
private readonly baseUrl: string
private readonly logger: Logger = new Logger(AlbumsService.name)

constructor(
private readonly httpService: HttpService,
private readonly configService: ConfigService
) {
this.baseUrl = this.configService.get<string>('api.baseurl')
}

async getUserAlbums(id: number): Promise<Album[]> {
const { data } = await firstValueFrom(
this.httpService.get<any[]>(`${this.baseUrl}/albums`).pipe(
catchError((err: AxiosError) => {
this.logger.error(err.response.data)
throw new BadRequestException("An error happened!")
})
)
)
return data.filter(o => o.userId === id)
}
}
18 changes: 18 additions & 0 deletions src/albums/photos/photos.service.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import { Test, TestingModule } from '@nestjs/testing';
import { PhotosService } from './photos.service';

describe('PhotosService', () => {
let service: PhotosService;

beforeEach(async () => {
const module: TestingModule = await Test.createTestingModule({
providers: [PhotosService],
}).compile();

service = module.get<PhotosService>(PhotosService);
});

it('should be defined', () => {
expect(service).toBeDefined();
});
});
32 changes: 32 additions & 0 deletions src/albums/photos/photos.service.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
import { HttpService } from '@nestjs/axios';
import { BadRequestException, Injectable, Logger } from '@nestjs/common';
import { ConfigService } from '@nestjs/config';
import { AxiosError } from 'axios';
import { catchError, firstValueFrom } from 'rxjs';
import { Photo } from 'src/graphql';

@Injectable()
export class PhotosService {
private readonly logger: Logger = new Logger(PhotosService.name)
private readonly baseUrl: string

constructor(
private readonly httpService: HttpService,
private readonly configService: ConfigService
){
this.baseUrl = this.configService.get<string>('api.baseurl')
}

async getPhotosByAlbumId(albumId: number): Promise<Photo[]> {
const { data } = await firstValueFrom(
this.httpService.get<any[]>(`${this.baseUrl}/photos`).pipe(
catchError((err: AxiosError) => {
this.logger.error(err.response.data)
throw new BadRequestException("An error happened!")
})
)
)

return data.filter(o => o.albumId === albumId)
}
}
14 changes: 8 additions & 6 deletions src/app.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import { join } from 'path';
import { AuthorModule } from './users/users.module';
import { PostsModule } from './posts/posts.module';
import { ConfigModule } from '@nestjs/config';
import { AlbumsModule } from './albums/albums.module';
import configuration from './config/configuration';

@Module({
Expand All @@ -20,15 +21,16 @@ import configuration from './config/configuration';
typePaths: ['./**/*.graphql'],
playground: true,
introspection: true,
// definitions: {
// path: join(process.cwd(), 'src/graphql.ts'),
// outputAs: 'class'
// },
definitions: {
path: join(process.cwd(), 'src/graphql.ts'),
outputAs: 'class'
},
}),
AuthorModule,
PostsModule
PostsModule,
AlbumsModule
],
controllers: [AppController],
providers: [AppService],
})
export class AppModule { }
export class AppModule {}
14 changes: 14 additions & 0 deletions src/graphql.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ export class User {
website?: Nullable<string>;
company?: Nullable<Company>;
posts?: Nullable<Nullable<Post>[]>;
albums?: Nullable<Nullable<Album>[]>;
}

export class Address {
Expand Down Expand Up @@ -53,6 +54,19 @@ export class Comment {
body?: Nullable<string>;
}

export class Album {
id: number;
title?: Nullable<string>;
photos?: Nullable<Nullable<Photo>[]>;
}

export class Photo {
id: number;
title?: Nullable<string>;
url?: Nullable<string>;
thumbnailUrl?: Nullable<string>;
}

export abstract class IQuery {
abstract users(): Nullable<Nullable<User>[]> | Promise<Nullable<Nullable<User>[]>>;

Expand Down
4 changes: 2 additions & 2 deletions src/posts/posts.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ export class PostsService {
return data
}

async getAuthorPosts(authorId: number): Promise<Post[]> {
async getUserPosts(userId: number): Promise<Post[]> {
const { data } = await firstValueFrom(
this.httpService.get<any[]>(`${this.baseUrl}/posts`).pipe(
catchError((err: AxiosError) => {
Expand All @@ -50,7 +50,7 @@ export class PostsService {
})
)
)
return data.filter(a => a.userId === authorId)
return data.filter(a => a.userId === userId)
}

async getPostComments(postId: number): Promise<Comment[]> {
Expand Down
14 changes: 14 additions & 0 deletions src/users/users.graphql
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ type User {
website: String
company: Company
posts: [Post]
albums: [Album]
}

type Address {
Expand Down Expand Up @@ -43,6 +44,19 @@ type Comment {
body: String
}

type Album {
id: Int!
title: String
photos: [Photo]
}

type Photo {
id: Int!
title: String
url: String
thumbnailUrl: String
}

type Query {
users: [User]
user(id: Int!): User
Expand Down
9 changes: 5 additions & 4 deletions src/users/users.module.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
import { Module } from '@nestjs/common';
import { AuthorsResolver } from './users.resolver';
import { AuthorService } from './users.service';
import { UsersResolver } from './users.resolver';
import { UserService } from './users.service';
import { HttpModule } from '@nestjs/axios';
import { PostsModule } from 'src/posts/posts.module';
import { AlbumsModule } from 'src/albums/albums.module';

@Module({
imports: [HttpModule, PostsModule],
providers: [AuthorsResolver, AuthorService]
imports: [HttpModule, PostsModule, AlbumsModule],
providers: [UsersResolver, UserService]
})
export class AuthorModule {}
28 changes: 18 additions & 10 deletions src/users/users.resolver.ts
Original file line number Diff line number Diff line change
@@ -1,30 +1,38 @@

import { Args, Parent, Query, ResolveField, Resolver } from "@nestjs/graphql";
import { Comment, Post, User } from "src/graphql";
import { AuthorService } from "./users.service";
import { Post, User } from "src/graphql";
import { UserService } from "./users.service";
import { PostsService } from "src/posts/posts.service";
import { AlbumsService } from "src/albums/albums.service";

@Resolver('User')
export class AuthorsResolver {
export class UsersResolver {

constructor(
private readonly authorService: AuthorService,
private readonly postsService: PostsService
private readonly userService: UserService,
private readonly postsService: PostsService,
private readonly albumService: AlbumsService
){}

@Query('users')
async authors(): Promise<User[]> {
return await this.authorService.getAuthors()
return await this.userService.getUsers()
}

@Query('user')
async author(@Args('id') id: number): Promise<User> {
return await this.authorService.getAuthor(id)
return await this.userService.getUserById(id)
}

@ResolveField('posts')
async getPosts(@Parent() author): Promise<Post[]> {
const { id } = author
return await this.postsService.getAuthorPosts(id)
async getPosts(@Parent() user): Promise<Post[]> {
const { id } = user
return await this.postsService.getUserPosts(id)
}

@ResolveField('albums')
async getAlbums(@Parent() user) {
const { id } = user
return await this.albumService.getUserAlbums(id);
}
}
8 changes: 4 additions & 4 deletions src/users/users.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@ import { catchError, firstValueFrom } from 'rxjs';
import { User } from 'src/graphql';

@Injectable()
export class AuthorService {
private readonly logger: Logger = new Logger(AuthorService.name)
export class UserService {
private readonly logger: Logger = new Logger(UserService.name)
private readonly baseUrl: string

constructor(
Expand All @@ -17,7 +17,7 @@ export class AuthorService {
this.baseUrl = this.configService.get<string>('api.baseurl')
}

async getAuthors(): Promise<User[]> {
async getUsers(): Promise<User[]> {
const { data } = await firstValueFrom(
this.httpService.get<User[]>(`${this.baseUrl}/users`).pipe(
catchError((error: AxiosError) => {
Expand All @@ -29,7 +29,7 @@ export class AuthorService {
return data
}

async getAuthor(id: number): Promise<User> {
async getUserById(id: number): Promise<User> {
const { data } = await firstValueFrom(
this.httpService.get<User>(`${this.baseUrl}/users/${id}`).pipe(
catchError((err: AxiosError) => {
Expand Down

0 comments on commit fd378e1

Please sign in to comment.